Go 语言史诗级更新-循环Bug修复

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

背景

前两天 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 test
name=b
name=a

在 1.22 发布后建议大家都可以升级了,将这种恶心的 bug 扼杀在摇篮里。

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

更多详情可以参看官方播客:https://go.dev/blog/loopvar-preview

责任编辑:武晓燕 来源: crossoverJie
相关推荐

2023-11-13 08:21:35

阿里云盘

2015-08-14 10:15:30

苹果更新

2022-02-09 08:21:43

累积更新微软Windows 10

2020-09-09 12:44:59

Windows 10微软Bug

2022-07-21 14:42:33

Windows 11BUG微软

2021-01-05 14:22:35

比特币货币投资

2023-07-27 07:24:49

2023-07-27 08:43:53

2023-04-06 08:00:00

JavaValhalla项目

2023-07-14 12:10:08

AI自主权离职

2015-10-22 10:09:03

ios9更新bug

2015-07-31 09:42:11

IOS更新

2021-06-24 05:40:28

Windows 10操作系统微软

2021-10-18 05:38:53

Windows 11操作系统微软

2019-10-17 10:12:02

Go语言Java函数

2022-05-23 09:22:20

Go语言调试器Delve

2021-07-08 23:53:44

Go语言拷贝

2009-02-20 16:53:07

Windows 7BetaBug

2022-09-14 08:28:31

微软Windows 11

2024-03-21 10:33:22

Windows 11微软
点赞
收藏

51CTO技术栈公众号