Go runtime version と go.mod の go ディレクティブとの関係
go 1.20.0
を実行
go1.23 で go.mod 概要
go.mod に go 1.20.0
と書いてあったとしてもインストールされているgoのバージョン(この例だとgo 1.23.2) で実行されます。
検証内容
module test
go 1.20.0
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Println("Go version :", runtime.Version())
}
上記ファイルがある状態で次のコマンドを実行すると Go version : go1.23.2
と出力される。
$ docker run -it --rm -v $(pwd):/work -w /work golang:1.23.2 go run main.go
Go version : go1.23.2
コンテナ内の環境変数は次のとおり
root@55b3ffdc026b:/work# printenv | grep GO
GOLANG_VERSION=1.23.2
GOTOOLCHAIN=local
GOPATH=/go
go 1.23
を実行
go1.20 で go.mod 概要
go.mod に go 1.23
と書いてあったとしても go 1.20.0 で go run
で一応実行可能です。
検証内容
module test
go 1.23
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Println("Go version :", runtime.Version())
}
上記ファイルがある状態で次のコマンドを実行すると Go version : go1.20
と出力される。
$ docker run -it --rm -v $(pwd):/work -w /work golang:1.20.0 go run main.go
Go version : go1.20
コンテナ内の環境変数は次のとおり
root@6856825db9f9:/work# printenv | grep GO
GOLANG_VERSION=1.20
GOPATH=/go
go 1.23
を実行(iteratorを使った場合)
go1.20 で go.mod 概要
go 1.23 で導入された iterator を使ったソースを go 1.20.0 で go run
しようとすると当たり前ですがエラーになります。
検証内容
module test
go 1.23
// https://zenn.dev/team_soda/articles/understanding-iterators-in-go
package main
import "fmt"
func iterator(yield func(int) bool) {
yield(1)
yield(2)
yield(3)
}
func main() {
for i := range iterator {
fmt.Println(i)
}
}
上記ファイルがある状態で次のコマンドを実行するとエラーになり実行できない。
$ docker run -it --rm -v $(pwd):/work -w /work golang:1.20.0 go run main.go
# command-line-arguments
./main.go:13:17: cannot range over iterator (value of type func(yield func(int) bool))
コンテナ内の環境変数は次のとおり
root@c8959549426b:/work# printenv | grep GO
GOLANG_VERSION=1.20
GOPATH=/go
go 1.23
を実行
go1.21 で go.mod 概要
go1.21以上の場合、ローカルにインストールされているgoバージョンが go.mod に書いてあるバージョンより低ければ実行できません。
ただし GOTOOLCHAIN
の設定次第では、自動的にgoがインストールされて実行されます事があります。
検証内容
module test
go 1.23
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Println("Go version :", runtime.Version())
}
上記ファイルがある状態で次のコマンドを実行するとエラーとなり go run
できない。
$ docker run -it --rm -v $(pwd):/work -w /work golang:1.21.13 bash
root@31b92f748888:/work# go run main.go
go: go.mod requires go >= 1.23 (running go 1.21.13; GOTOOLCHAIN=local)
root@31b92f748888:/work# printenv | grep GO
GOLANG_VERSION=1.21.13
GOTOOLCHAIN=local
GOPATH=/go
GOTOOLCHAIN
を auto
にすると、自動的に go1.23.0
がダウンロードされて実行できます。
root@31b92f748888:/work# GOTOOLCHAIN=auto
root@31b92f748888:/work# go run main.go
go: downloading go1.23.0 (linux/amd64)
Go version : go1.23.0
参考記事
go 1.19
を実行
go1.20 で go.mod 概要
go.mod に go 1.19
と書いてあったとしてもインストールされているgoのバージョン(この例だとgo1.20.14) で実行されます。
検証内容
module test
go 1.19
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Println("Go version :", runtime.Version())
}
上記ファイルがある状態で次のコマンドを実行すると Go version : go1.20.14
と出力される。
$ docker run -it --rm -v $(pwd):/work -w /work golang:1.20.14 go run main.go
Go version : go1.20.14
コンテナ内の環境変数は次のとおり
root@baec59ee9ffa:/work# printenv | grep GO
GOLANG_VERSION=1.20.14
GOPATH=/go
現在go 1.21以上を使っている人が多いと思いますので、とりあえずgo.modのgoディレクティブには動作可能な最小バージョンを記載すると思っておけば良さそうです。
記事にまとめたので詳しくはこちらをご参照ください。