go 1.22 关于 for 循环问题的困惑

Kenny · 2024-9-29 10:44:33 · 248 次点击

在发布 go 1.22 版本时,注意到了 for 循环有一个变更,简单就是说从之前的共享变量,调整为每次执行循环步都会重新实例化变量,这样避免了闭包中共享变量导致的并发问题。 于是今天通过代码模拟发生了一个令人困惑的问题,不同的执行方式,导致不同的结果,相同的代码:


func main() {
done := make(chan bool)

values := []string{"chen", "ming", "yong"}
for _, v := range values {
go func() {
fmt.Println(v)
done <- true
}()
}

// 结束前等待所有的 goroutine 执行成
for _ = range values {
<-done
}
}

当我使用 go run . 打印结果的时候为 (这显然是不正常的):


❯ go run .
yong
yong
yong

但是当我使用 go run main.go 打印结果确是正常的。这是为什么,是 bug 吗?还是本应该如此:


❯ go run main.go
yong
ming
chen

同时提交了 issue : import/path: Loops no longer share loop variablesRunning them in different ways gives different results · Issue #69704 · golang/go · GitHub


有没有大佬解答一下小弟的困惑

举报· 248 次点击
登录 注册 站外分享
9 条回复  
cabbage 初学 2024-9-29 10:44:33

这边建议问下gpt呢

little_dingdang 初学 2024-9-29 10:44:33



我拿你代码试下你提到的两种情况没区别啊,你是不第一次没保存 :xhs_021:

admini 初学 2024-9-29 10:44:33

看见你在 golang 提 bug 了啊。

1713375484 初学 2024-9-29 10:44:33

借楼问一个问题,golang的反序列化方法,假如这是一个待解析的json

{

“id”: “1”,

“name”: “2”,

“email”: “3”

}


那么json.Unmarshal的第二个参数应该要传递一个指针类型的map或者结构体,结构体传引用类型好理解,但是map本身就是引用类型,为什么还要传一个引用类型的map呢,这不是多次一举么,gpt给我回答的等于没回答…

dazuixia 初学 2024-9-29 10:44:33

你这语法本身就有问题. 需要用到 数组元素 都是 传参 进去的. 而不是 直接获取 外界变量的. 我5年go开发

1231 初学 2024-9-29 10:44:33

新特性如果go.mod中golang的版本比较低是不会生效的,一般通过go run好像是可以生效的

laosiji 初学 2024-9-29 10:44:33

go run . 会使用 go.mod 文件中的 go 版本来确定编译行为和标准库函数的使用。如果 go.mod 中没有指定 go 版本,Go 会选择一个默认的最低兼容版本来编译当前目录下的所有 main 包的文件。


go run main.go 也会使用 go.mod 中的版本来确定编译行为,但有时在没有 go.mod 的情况下,它可能使用当前环境中的 Go 编译器版本(即安装的 Go 版本)


go的1.23版本修改并发for对应的item问题,可能最低版本还是老版本所以全部打印一样数据

WhyNo 初学 2024-9-29 10:44:33

知道go run .和go run main.go的编译行为是有差异的,同时go mod文件中的go版本号会影响编译器的行为,但是具体不是很了解。

请问您描述的这个差异,能给一个官方文档的链接吗?

想学习一下,谢谢

looper12 初学 2024-9-29 10:44:33

yong

yong

yong


这个不是正确输出吗

返回顶部