Open6

Go runtime version と go.mod の go ディレクティブとの関係

demouthdemouth

go1.23 で go.mod go 1.20.0 を実行

概要

go.mod に go 1.20.0 と書いてあったとしてもインストールされているgoのバージョン(この例だとgo 1.23.2) で実行されます。

検証内容

go.mod
module test

go 1.20.0
main.go
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
demouthdemouth

go1.20 で go.mod go 1.23 を実行

概要

go.mod に go 1.23 と書いてあったとしても go 1.20.0 で go run で一応実行可能です。

検証内容

go.mod
module test

go 1.23
main.go
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
demouthdemouth

go1.20 で go.mod go 1.23 を実行(iteratorを使った場合)

概要

go 1.23 で導入された iterator を使ったソースを go 1.20.0 で go run しようとすると当たり前ですがエラーになります。

検証内容

go.mod
module test

go 1.23
main.go
// 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
demouthdemouth

go1.21 で go.mod go 1.23 を実行

概要

go1.21以上の場合、ローカルにインストールされているgoバージョンが go.mod に書いてあるバージョンより低ければ実行できません。

ただし GOTOOLCHAIN の設定次第では、自動的にgoがインストールされて実行されます事があります。

検証内容

go.mod
module test

go 1.23
main.go
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

GOTOOLCHAINauto にすると、自動的に 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

参考記事

https://speakerdeck.com/yamatoya/go1-dot-21karadao-ru-sareta-go-toolchainnoshi-zu-miwomarututojie-shuo

demouthdemouth

go1.20 で go.mod go 1.19 を実行

概要

go.mod に go 1.19 と書いてあったとしてもインストールされているgoのバージョン(この例だとgo1.20.14) で実行されます。

検証内容

go.mod
module test

go 1.19
main.go
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
demouthdemouth

現在go 1.21以上を使っている人が多いと思いますので、とりあえずgo.modのgoディレクティブには動作可能な最小バージョンを記載すると思っておけば良さそうです。

記事にまとめたので詳しくはこちらをご参照ください。
https://zenn.dev/demouth/articles/716ea17e6416ed