Go の go run でパッケージが実行できない(package is not a main package)
`go run` は `package main` で `func main()` を持つパッケージしか実行できない。
ライブラリ側のディレクトリを指定したり、`package foo` のままだとこのエラーになる。
#run#package#main#build
公開:
要約
go run に渡したパッケージが package main でない、もしくは func main() を持っていないとこのエラーになります。
ライブラリ用パッケージは go run の対象にできません。
実行用エントリは必ず package main と func main() を持つ別ディレクトリ(例: cmd/myapp)に置きます。
// cmd/myapp/main.go
package main
func main() {
// ...
}よくある原因
package main宣言が無い: ライブラリ用のディレクトリでpackage fooのままgo run .を叩いた。
Go はライブラリパッケージを直接実行する手段を持たない。func main()の欠落: 宣言はpackage mainだが本体関数が無いと別バリエーションのエラー(function main is undeclared等)になる。- ディレクトリ指定が違う: モジュールルートで
go run .を叩いたが、エントリはcmd/myapp/配下に置いていた。 - ファイル単体指定で関連ファイルが足りない:
go run main.goだけ叩いたが、mainから呼ぶ関数が別ファイルにある場合、それらも引数に並べる必要がある。
解決策
1. エントリポイントを cmd/ 配下に分離する
Go の慣習レイアウトでは、ライブラリ本体はモジュールルート直下、CLI エントリは cmd/<name>/main.go に置きます。
myapp/
├── go.mod
├── foo.go // package myapp(ライブラリ)
└── cmd/
└── myapp/
└── main.go // package main + func main()実行は次の通り。
go run ./cmd/myapp2. ファイル単体実行する場合
go run main.go helper.gomain パッケージ内のすべての .go ファイルを並べます。
ディレクトリ指定 (go run ./cmd/myapp) の方が漏れがなく安全です。
3. 「ビルドはできるが run できない」場合
ライブラリは go build ./... で型チェックは通りますが、go run は通りません。
CLI として動かしたいなら必ず main パッケージに分離してください。