📝
`go`ディレクティブ (荒訳)
go
ディレクティブについての説明 https://go.dev/ref/mod#go-mod-file-go の荒訳です。
go
ディレクティブ
go
ディレクティブは、そのモジュールがどのバージョンのGoのセマンティクスを想定して書かれたかを示します。このバージョンはGoの有効なリリースバージョンで、正の整数にドット及び負ではない整数が続きます。(例: 1.9
, 1.14
)
go
ディレクティブはもともとGo言語の後方互換性のない変更(Go 2への移行を参照)をサポートするためのものでした。モジュールが導入されて以来、互換性のない言語の変更は導入されていませんでしたが、go
ディレクティブは言語の新機能の使用に影響を及ぼします:
- あるモジュール内のパッケージにおいて、コンパイラは
go
ディレクティブで指定されたバージョン以降に導入された機能の利用を拒否します。例えばモジュールにgo 1.12
ディレクティブがあった場合、そのモジュール内のパッケージではGo 1.13で導入された1_000_000
のような数値リテラルは利用できません。 - 古いバージョンのGoを用いてあるモジュールのパッケージをビルドしコンパイラーエラーに遭遇した場合、そのモジュールはより新しいバージョンのGoに向けて書かれたことがエラーメッセージからわかります。例えばあるモジュールに
go 1.13
ディレクティブが書かれ、数値リテラル1_000_000
を使っている場合に、そのパッケージをGo 1.12でビルドしようとするとコンパイラはコードがGo 1.13用に書かれていることを知らせてくれます。
加えてgo
コマンドはgo
ディレクティブに書かれたバージョンに基づいてその振る舞いを変えます。具体的には以下のような影響があります:
-
go 1.14
以降では、自動ベンダリングが有効になる場合があります。vendor/modules.txt
ファイルが存在しgo.modと整合性がとれていれば、明示的に-mod=vendor
フラグを与える必要はなくなります。 -
go 1.16
以降では、all
パッケージパターンはメインモジュール (訳注:go
コマンドが実行されたモジュール)のパッケージやテストから推移的にインポートされるパッケージにのみマッチします。これはモジュールが導入されて以来go mod vendor
で取得できるパッケージのセットと同じです。より古いバージョン(訳注: たぶんgo 1.15
以前)ではall
はメインモジュールのパッケージによりインポートされるパッケージのテストや、それらのパッケージのテストなどもすべて含まれています。 -
go 1.17
以降では以下の影響があります:-
go.mod
ファイルに、メインモジュール内のパッケージ及びテストにより推移的にインポートされるパッケージを提供するモジュールのための明示的なrequire
ディレクティブを1つ含みます。(go 1.16
以前では最小限バージョン選択戦略において最小ではないバージョンを選択される際に間接的な依存(indirect dependency)として含まれます。)この追加情報はモジュールグラフの刈り込みとモジュールの遅延読み込みを実現するのに使われます。 -
go
の以前のバージョンよりも多くの// indirect
な依存が含まれる場合があるので、間接的依存はgo.mod
ファイル内の独立したブロックに記録されます。 -
go mod vendor
コマンドはgo.mod
とgo.sum
ファイルをベンダーされた依存モジュールについては省略します。(これにより、vendor
ディレクトリ内のサブディレクトリでgo
コマンドを実行した際に、正しいメインモジュールを特定できるようなります。) -
go mod vendor
コマンドは、ベンダーされた依存モジュール内のgo.mod
ファイルに記載されたgo
ディレクティブのバージョンをvendor/modules.txt
に記録します。
-
1つのgo.mod
ファイルは最大1個のgo
ディレクティブを含められます。ほとんどのコマンド(訳注: おそらくgo mod
コマンドのサブコマンドのこと)はgo.mod
ファイルにgo
ディレクティブが含まれていなかった場合に現在のGoのバージョンでgo
ディレクティブを追加します。
GoDirective = "go" GoVersion newline .
GoVersion = string | ident . /* valid release version; see above */
例:
go 1.14
訳者メモ
コンパイルに使うgo
コマンドのバージョンよりも新しいバージョンがgo
ディレクティブ記載されていても即座にエラーになるわけではないことに留意が必要です。つまりgo 1.13
と書かれたモジュールであってもgo 1.13
固有の記法やスタンダードパッケージや機能を使っていないならば、Go 1.12でビルドできます。
Discussion