Go 1.22 将修复 for 循环变量错误

来源: OSCHINA
编辑:
2023-09-21 18:34:00

上月正式发布的 Go 1.21 修改了 for 循环变量的语义(预览阶段,点此查看详情)。

现在,Go 团队表示 Go 1.22 会将这项特性发布为正式功能

根据 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
    }
}

其创建的三个 goroutine 都用于打印相同的变量v,因此它们只会打印出 “c”, “c”, “c”,而不是按顺序打印 “a”, “b”, 和 “c”。

从 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 下默认启用。

展开阅读全文
点击加入讨论🔥(18) 发布并加入讨论🔥
本篇精彩评论
笑死,之前还有人洗是为了效率,现在还说屁
2023-09-22 18:29
2
举报
这种情况在Rust中不可能出现,因为Rust有所有权机制,还有闭包还move关键字。
2023-09-22 09:11
2
举报
是这个意思
2023-09-23 08:48
1
举报
啥意思?
go func() {
fmt.Println(v)
done <- true
}() 这段代码以前循环结束,打印的都是c,1.22版之后可以打印出a,b,c?
2023-09-23 00:45
1
举报
😂😂梦回JS?
2023-09-21 23:20
1
举报
18 评论
4 收藏
分享
返回顶部
顶部