 golang 1.22からこの問題は発生しなくなっています 参考: https://go.dev/blog/go1.22
  golang 1.22からこの問題は発生しなくなっています 参考: https://go.dev/blog/go1.22
golang 1.22未満の goのforループ変数は同じ変数を共有します。
ループ内の変数の処理を後から利用しようとするとループの最後の値になってしまいます。deferとかの時にバグをうみやすいので注意が必要です。
// loop_scope.go
package main
import (
	"fmt"
)
func main() {
	strings := []string{"a", "b", "c"}
	var printFuncList []func()
	// ループ変数sは各ループ処理で使い回されるので、無名関数からは同じ変数の値が表示されてしまいます
	for _, s := range strings {
		printFuncList = append(printFuncList, func() {
			fmt.Printf("s = \"%s\" (%p)\n", s, &s)
		})
	}
	// 何らかの処理
	for _, printFunc := range printFuncList {
		printFunc()
	}
}
実行すると、最後の変数の値の"c"が表示されてしまいます。
// 実行結果(1.21.7 で確認)
go run loop_scope.go
s = "c" (0x14000010070)
s = "c" (0x14000010070)
s = "c" (0x14000010070)
// 実行結果(1.22.0 で確認)
go run loop_scope.go
s = "a" (0x14000090040)
s = "b" (0x14000090060)
s = "c" (0x14000090090)
そのため、変数宣言をする必要があります。
// loop_scope.go
package main
import (
	"fmt"
)
func main() {
	strings := []string{"a", "b", "c"}
	var printFuncList []func()
	for _, s := range strings {
		s := s // この変数宣言が必要
		printFuncList = append(printFuncList, func() {
			fmt.Printf("s = \"%s\" (%p)\n", s, &s)
		})
	}
	// 何らかの処理
	for _, printFunc := range printFuncList {
		printFunc()
	}
}
今度は、"a", "b", "c"とそれぞれの変数の値の"c"が表示される用になります。
// 実行結果
go run loop_scope.go
s = "a" (0x14000102020)
s = "b" (0x14000102040)
s = "c" (0x14000102070)