
main.goファイルだけでプログラムのコードを書くと、とても読みにくいんですが…
今回はGo言語のパッケージ管理の基本をお伝えしていきます。
当ブログの入門編では main.go
ファイルひとつでプログラムの動きを確認していきました。
Goの文法を学習するには main.go
だけで問題ないのですが、アプリ開発ともなればプログラムの行数が多くなり確認作業も大変です。
Goでは、あなたが管理しやすいように機能ごとなどにファイルを分割してパッケージを自作することができます。
この記事では、パッケージ管理の基本的なことを理解していきましょう。
今回の学習するパッケージ管理の構成
今回は下記のようなパッケージ管理の構成にします。
morip@morip-PC1:~/go/src/package$ tree
.
├── go.mod
├── main.go // プログラムのメイン
└── myapp // フォルダ名をパッケージ名に
├── myfunc.go // 関数を管理するファイル
└── myvar.go // 定数・変数を管理するファイル
1 directory, 4 files

src
フォルダの直下にしないとエラーの原因になります。
パッケージ管理の前準備
goのバージョン1.13から go mod
でモジュール管理が推奨されていますので、go mod
モジュールをインストールする必要があります。
まずは、ターミナルを開いてからパッケージ管理するフォルダまで移動します。
cd
コマンドで移動したら go mod init
と入力して実行しましょう。
// パッケージ管理の前準備
morip@morip-PC1:~/go/src$ cd package/
morip@morip-PC1:~/go/src/package$ go mod init
go: creating new go.mod: module ini_test
go: to add module requirements and sums:
go mod tidy
「依存パッケージの管理のために go mod tidy
コマンドを実行してください」という内容のメッセージがでますが、今の段階で go mod tidy
コマンドを実行すると…
// go mod tidyの実行結果
morip@morip-PC1:~/go/src/package$ go mod tidy
morip@morip-PC1:~/go/src/package$

何も実行されません。
go mod tidy
コマンドの実行は、プログラムファイルを実行する時に行いましょう。
go mod tidy
は不要な依存パッケージの削除や追加を行ってくれるコマンドです。
今の段階では、下記のファイル構成でOKです。
morip@morip-PC1:~/go/src/package$ tree
.
├── go.mod // go.modが自動で作成される
├── main.go // プログラムのメイン
go mod init
しなくてもプログラムコードを書いているときはエラーにはなりませんが、環境によっては go run main.go
を実行すると…
$ go run main.go
main.go:5:2: package package/myapp is not in GOROOT (/usr/lib/go-1.16/src/package/myapp)
というエラーになるかもしれません。
エラー回避のためにも go mod init
は実行しておきましょう。
パッケージ管理実践編
それではパッケージ管理を実践していきます。
パッケージフォルダの作成とファイル作成
下記のような構成を作成していきましょう。
morip@morip-PC1:~/go/src/package$ tree
.
├── go.mod
├── main.go // プログラムのメイン
└── myapp // フォルダ名をパッケージ名に
└── myvar.go // 定数・変数を管理するファイル
各ファイルの内容は下記の通りです。
// myvar.go
package myapp // パッケージ名
const (
Max = 100
Min = 1
)
var Age int = 51
// main.go
package main
import (
"fmt"
"package/myapp" // package myappをインポート
)
func main() {
// 定数呼び出し
fmt.Println(myapp.Max)
fmt.Println(myapp.Min)
// 変数呼び出し
fmt.Println(myapp.Age)
}
myvar.go
はパッケージ名として package myapp
と宣言しています。
main.go
では、myvar.go
の変数と定数を利用するために "package/myapp"
と import
で宣言しています。

では、出力結果を確認しましょう。
// 出力結果
$ go run main.go
100
1
51
package myapp
の変数と定数が無事に package main
から出力されました。
他のパッケージから関数を呼び出してみよう
他のパッケージ(main package以外)で定義した関数を呼び出して実行してみます。
morip@morip-PC1:~/go/src/package$ tree
.
├── go.mod
├── main.go // プログラムのメイン
└── myapp // フォルダ名をパッケージ名に
├── myfunc.go // 関数を管理するファイル(今回はここ)
└── myvar.go
1 directory, 4 files
myapp
フォルダの直下に myfunc.go
というファイルを作成します。
スライスの値の平均値を戻り値にしたプログラムで、下記のようにコードを記述してみました。
// myfunc.go
package myapp
func Ave(sl []int) int {
// 合計用変数
sum := 0
// スライスの値を取り出す(インデックス不要)
for _, v := range sl {
// 合計を求める
sum += v
}
// 戻り値で平均値を返す
return int(sum / len(sl))
}
// main.go
package main
import (
"fmt"
"package/myapp"
)
func main() {
// スライス作成
sl := []int{10, 20, 30, 40, 50}
// myapp.Ave()を呼び出して実行
a := myapp.Ave(sl)
fmt.Println(a)
}
// 出力結果
$ go run main.go
30

無事に myfunc.go
の myapp.Ave
を実行することができました!
パブリックとプライベート
myvar.go
のプログラムを利用して、パブリックとプライベートについてお伝えしましす。
// myvar.go
package myapp // パッケージ名
const (
Max = 100
min = 1 // minの頭文字を小文字に変更
)
var Age int = 51
Go言語ではパブリックは大文字、プライベートでは小文字で記述します。
パブリックは外部のパッケージから読み込むことができますが、プライベートは同一ファイル内からのみ読み込み可能で外部からは読み込みできません。
// 出力結果
$ go run main.go
# command-line-arguments
./main.go:11:17: cannot refer to unexported name myapp.min
「エクスポートされていない名前を参照することはできません」というエラーになります。
ただし、下記のように関数を通して読み込むこともできます。
// myvar.go
package myapp // パッケージ名
const (
Max = 100
min = 1 // minの頭文字を小文字に変更
)
// 小文字でも同一ファイル内はOK
func Exp() {
fmt.Println(min)
}
// main.go
package main
import (
"fmt"
"package/myapp"
)
func main() {
// 定数呼び出し
fmt.Println(myapp.Max)
// 下記はエラー
// fmt.Println(myapp.min)
// 関数を通して呼び出し
myapp.Exp()
}
// 出力結果
$ go run main.go
100
1 // 定数minを呼び出し
あまり使用されることはありませんが、パブリックとプライベートの違いを理解していただけるでしょう。
【まとめ】Go言語のパッケージ管理の基本
今回はGo言語のパッケージ管理の基本についてお伝えしてきました。
それでは、まとめにはいりましょう。
以上です。
今回の例はあくまでも学習のため(プログラムの動きを確認するため)のパッケージ管理となります。
実際のアプリ開発では、設計段階でパッケージ構成が決定されるでしょう。
個人がGo言語でアプリ開発するにしても、main.go
ファイルだけでは管理できなくなるはずです。
ぜひパッケージ管理の基本は押さえておきましょう。
comment