根据 Go 开发团队技术 leader Russ Cox (rsc) 的介绍,Go 开发者经常会犯的错误是在循环迭代结束后,保留对循环变量的引用,此时它会采用预期之外的新值。
例如下面的程序:
func main() {
done := make(chan bool)
values := []string{"a", "b", "c"}
for _, v := range values {
go func() {
fmt.Println(v)
done <- true
}()
}
// wait for all goroutines to complete before exiting
for _ = range values {
<-done
}
}
从 Go1.21 开始,开发者可以启用GOEXPERIMENT=loopvar来构建 Go 程序,以解决上文提到的 for 循环变量问题。
构建命令:
GOEXPERIMENT=loopvar go install my/program
GOEXPERIMENT=loopvar go build my/program
GOEXPERIMENT=loopvar go test my/program
GOEXPERIMENT=loopvar go test my/program -bench=.
...
现在 Go 开发团队表示,从 Go1.22 开始,新的 for 循环语义将会在 go.mod 文件中的 Go 版本大于等于 Go1.22 下默认启用。
Go 1.22 将修复 for 循环变量错误
上月正式发布的 Go 1.21 修改了 for 循环变量的语义(预览阶段,点此查看详情)。
现在,Go 团队表示 Go 1.22 会将这项特性发布为正式功能。
根据 Go 开发团队技术 leader Russ Cox (rsc) 的介绍,Go 开发者经常会犯的错误是在循环迭代结束后,保留对循环变量的引用,此时它会采用预期之外的新值。
例如下面的程序:
其创建的三个 goroutine 都用于打印相同的变量
v
,因此它们只会打印出 “c”, “c”, “c”,而不是按顺序打印 “a”, “b”, 和 “c”。从 Go1.21 开始,开发者可以启用
GOEXPERIMENT=loopvar
来构建 Go 程序,以解决上文提到的 for 循环变量问题。构建命令:
现在 Go 开发团队表示,从 Go1.22 开始,新的 for 循环语义将会在 go.mod 文件中的 Go 版本大于等于 Go1.22 下默认启用。