今はプロジェクトでバージョンの固定にgoenvを利用しているが、
「Go 1.21以降では、go.modに記載されたgoのバージョンがインストールされていない場合、自動でダウンロードして指定のバージョンのgoで実行されるためGoenvが不要になる。」
という話を聞いたので、Go公式が用意したツールチェインを利用した方法で、
マイナーバージョンも含めてGoのバージョンをプロジェクトごとに固定出来るか、検証した。
検証
事前準備
go1.21.1のインストール
$ go install golang.org/dl/go1.21.1@latest
$ go1.21.1 download
$ go1.21.1 version
$ go1.21.1 env GOROOT
/Users/mitsuaki.ihara/sdk/go1.21.1
$ go version go1.21.1 darwin/arm64
go.modの作成及び検証用ファイル作成
Goのプロジェクトを初期化する。
$ go mod init example.com/m
go: creating new go.mod: module example.com/m
適当にGoファイルを作る。
$ vi main.go
// You can edit this code!
// Click here and start typing.
package main
import "fmt"
func main() {
fmt.Println("Hello, 世界")
}
検証実施
同じバージョン
$ go mod edit -go=1.21.1
$ go1.21.1 build
$ go1.21.1 env GOROOT
/Users/mitsuaki.ihara/sdk/go1.21.1
未来のバージョン
$ go mod edit -go=1.21.3
$ go1.21.1 build
go: downloading go1.21.3 (darwin/arm64)
$ go1.21.1 env GOROOT
/Users/mitsuaki.ihara/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.3.darwin-arm64
過去のバージョン
$ go mod edit -go=1.21.0
$ go1.21.1 build
$ go1.21.1 env GOROOT
/Users/mitsuaki.ihara/sdk/go1.21.1
検証結果
go.modに指定されたGoのバージョンが、インストールされているGoのバージョンより未来のバージョンの場合、インストールされていない場合は、ツールチェインにダウンロードし、GOROOTに設定しつつビルドを行い、
go.modに指定されたGoのバージョンが、インストールされているGoのバージョンより過去のバージョンの場合、1番近いバージョンをGOROOTに設定しつつビルドを行う模様。
上記から、マイナーバージョンも含めてGoのバージョンをプロジェクトごとに固定する事は出来なさそう。
ChatGPTもそう言っている。
Go 1.21.0以降では、go.modファイルに記載されたバージョンは、使用するGoのツールチェーンの最低バージョンを指定します。
つまり、このバージョン以降の任意のバージョンでビルドが可能になります。
特定のバージョンのみを使用してビルドを固定する機能は、標準のGoツールチェーン管理システムには含まれていません。
そのため、go.modに記載されているバージョンは、そのバージョン以上であればどのバージョンを使用しても構わないという意味になります。
特定のバージョンでのビルドを保証するには、他の方法を検討する必要があります。
だが、関連の記事を見る限り、過去互換性があるため、ある程度の頻度でバージョンを追うことが前提になるが、基本的にはそこまで問題ないようにも見える。
ChatGPTもそう言っている。
Goのバージョン1.21.0以降では、後方互換性が重視されています。
つまり、go.modでGo 1.21.0を指定している場合、Go 1.21.5などの後のバージョンでビルドしても問題ありません。
Goの開発チームは、新しいバージョンのリリース時に後方互換性を維持することに力を入れており、古いバージョンで書かれたコードが新しいバージョンでも動作するように努めています。
ただし、非推奨になった機能や削除された機能に依存しているコードは、更新が必要になることがあります。