📝
`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