go.modのバージョンはどれを選べばいいのか
This content is a draft and will not be included in production builds.
- Go 1.20までは、
goディレクティブにはモジュールがサポートする下限バージョンを書けばよかった - Go 1.21から、
toolchainディレクティブが登場したのでよくわからなくなったtoolchainを省略するとgoの値が使われる
goとtoolchainをどう選べばいいのか整理したい
go1.22時点でのまとめ
Section titled “go1.22時点でのまとめ”- ライブラリの
goディレクティブは、ライブラリがサポートする下限バージョンを3桁で設定する toolchainディレクティブはなんでもいい
- Forward Compatibility and Toolchain Management in Go 1.21
- Go Toolchains
- Perfectly Reproducible, Verified Go Toolchains
- モジュールをビルドするための下限となるGoバージョンを記述する
- 言語バージョン = 1.xまで(1.21.2, 1.21rc1どれも1.21)
>= 1.21: 1.21 < 1.21rc1 < 1.21.0 < 1.21.1 < 1.22<1.21: 1.20rc1 < 1.20rc2 < 1.20rc3 < 1.20 < 1.20.1- 1.21形式の位置が違うの難しいが、過去の習慣でそうなっていたので無視できない
- Goバージョンは
1.22や1.21.4など2桁または3桁のバージョンを使う - このバージョンによって利用できる言語機能が変わる
- (調べる)1.21以降、言語の機能にのみ影響する(genericsとか
1_00など) - 参照する他のモジュールにも影響する
- モジュールMは、Mが依存するすべてのモジュールでいちばん新しいバージョンと同じか新しいバージョンが必要
go 1.21.1のモジュールで//go:build 1.22を含むことは許されるgo get go@1.21.0で更新-
That is, the go line sets the minimum required Go version necessary to use a module or workspace.
- 推奨するGoツールチェーンのバージョンを記述する
- ツールチェーンは標準ライブラリとコンパイラやアセンブラなどの総称
- このバージョンより以前のツールチェーンではビルドできなくなる
- mainモジュールであり、デフォルトのツールチェーン(?)が
toolchainより小さい場合にのみ効果がある - ツールチェーンバージョンは
go1.22.0のようにgoprefixが必要 - 省略すると
goの値が使われる- ただし
go1.22のような2桁のバージョンは開発用なので、省略する場合のgoディレクティブは3桁まで書く
- ただし
- モジュール自身をビルド/テストするときに利用されるが、モジュールの外には影響しない?
go get toolchain@go1.21.0で更新GOTOOLCHAIN=go1.21.1 go test(default=auto)
GOTOOLCHAIN
Section titled “GOTOOLCHAIN”| GOTOOLCHAIN | アップグレード | $PATH検索 | ダウンロード | 新しい場合 | 満たない場合 |
|---|---|---|---|---|---|
| go1.22.0 | する | する | する | エラー | エラー |
| go1.22.0+auto | する | する | する | ビルド | |
| go1.22.0+path | する | する | しない | ||
| auto (local+auto) | する | する | する | ビルド | |
| path (local+path) | |||||
| local | しない | しない | しない | ビルド | エラー |
| default | しない | しない | しない | エラー | エラー |
setup-goのgo-version-file
Section titled “setup-goのgo-version-file”go-version-fileでは、まだtoolchainディレクティブをみていない
なぜ必要なのか
Section titled “なぜ必要なのか”- 前方互換性のため
- 後方互換性は「古いバージョンで書かれたGoのコードを新しいバージョンのツールチェーンでコンパイルできる」こと
- 前方互換性は「新しいバージョンで書かれたGoのコードを古いバージョンのツールチェーンでコンパイルできる」こと
- そこまでする必要ある?
- モジュールが特定のバージョンを必要としているとき、それより古いバージョンでたまたまビルドできてしまう事態を防ぎたいらしい
- なんだけど、単に制限するだけだと不快なので、
toolchain version > current go versionの場合はtoolchainのGoバージョンを内部でダウンロードしてそれを使うようになった