Skip to content

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の値が使われる
  • gotoolchainをどう選べばいいのか整理したい
  • ライブラリのgoディレクティブは、ライブラリがサポートする下限バージョンを3桁で設定する
  • toolchainディレクティブはなんでもいい
  • モジュールをビルドするための下限となる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.221.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 のようにgo prefixが必要
  • 省略するとgoの値が使われる
    • ただしgo1.22のような2桁のバージョンは開発用なので、省略する場合のgoディレクティブは3桁まで書く
  • モジュール自身をビルド/テストするときに利用されるが、モジュールの外には影響しない?
  • go get toolchain@go1.21.0で更新
  • GOTOOLCHAIN=go1.21.1 go test (default=auto)
GOTOOLCHAINアップグレード$PATH検索ダウンロード新しい場合満たない場合
go1.22.0するするするエラーエラー
go1.22.0+autoするするするビルド
go1.22.0+pathするするしない
auto (local+auto)するするするビルド
path (local+path)
localしないしないしないビルドエラー
defaultしないしないしないエラーエラー
  • go-version-fileでは、まだtoolchainディレクティブをみていない
  • 前方互換性のため
  • 後方互換性は「古いバージョンで書かれたGoのコードを新しいバージョンのツールチェーンでコンパイルできる」こと
  • 前方互換性は「新しいバージョンで書かれたGoのコードを古いバージョンのツールチェーンでコンパイルできる」こと
    • そこまでする必要ある?
    • モジュールが特定のバージョンを必要としているとき、それより古いバージョンでたまたまビルドできてしまう事態を防ぎたいらしい
    • なんだけど、単に制限するだけだと不快なので、 toolchain version > current go version の場合はtoolchainのGoバージョンを内部でダウンロードしてそれを使うようになった