背景

前两天 Golang 的官网博客更新了一篇文章:Fixing For Loops in Go 1.22

看这个题目的就是修复了 Go 循环的 bug,这真的是史诗级的更新;我身边接触到的大部分 Go 开发者都犯过这样的谬误,包含我本人,所以前两年我也写过相似的博客:
简略的 for 循环也会踩的坑

先来简略回顾下应用应用 for 循环会碰到的问题:

list := []*Demo{{"a"}, {"b"}}  for _, v := range list {      go func() {          fmt.Println("name="+v.Name)      }()  }    type Demo struct {      Name string  }

预期的后果应该是打印 a,b,但理论打印的却是b,b

Let's Encrypt: CAA Rechecking bug
相似的问题连 mozilla 团队也没能幸免,所以也的确是一个十分常见的问题,这样的写法合乎大部分的开发者的直觉,毕竟其余语言这么应用也没有问题。

当然在现阶段要解决也很简略,要么就是在应用之前先复制一次,或者应用闭包传参:

 // 复制 list := []*Demo{{"a"}, {"b"}}   for _, v := range list {    temp:=v    go func() {     fmt.Println("name="+temp.Name)    }()   } // 闭包 list := []*Demo{{"a"}, {"b"}}   for _, v := range list {    go func(temp *Demo) {     fmt.Println("name="+temp.Name)    }(v)   }

还好官网也意识到了这个问题:

所以在 1.22 中咱们能够不必再写这个 



v:=v这个多余的复制语句了,也不会呈现下面的问题。

咱们在 1.21 中能够应用环境变量预览这个个性:

❯ GOEXPERIMENT=loopvar go testname=bname=a

在 1.22 公布后倡议大家都能够降级了,将这种恶心的 bug 扼杀在摇篮里。

1.22 后带来了一个好消息是今后少了一道面试题,坏消息是又新增了一个 1.22 版本带来了哪些变动的面试题

更多详情能够参看官网播客:https://go.dev/blog/loopvar-preview