又过了好几个月,到了 Go 新版本的日子了。Go 1.22 已于 2024 年 2 月发布。今天这篇文章主要是针对 for 循环的特性变更,是一个重要变更,说是特性其实是嘴硬,以前那么设计导致为了避免出BUG代码写出来看着特别的傻缺,再尬吹Go语言优雅的人看了估计心里都得臭骂一顿。具体咋回事呢?听我跟你细说。
func main() { values := []int{1, 2, 3, 4, 5} for _, val := range values { go func() { fmt.Printf("%d ", val) }() } time.Sleep(time.Second * 3) }输出结果:
5 5 5 5 5如果是 Go1.22 以前的版本,在不做任何变更的情况下。我们需要把代码改成如下:
func main() { values := []int{1, 2, 3, 4, 5} for _, val := range values { go func(val int) { fmt.Printf("%d ", val) }(val) } time.Sleep(time.Second * 3) }其他场景下,也会需要写 v := v 的代码来再次赋值。经典的很。但在 Go1.22 起,不再需要这么干了。之前文章《Go 团队将修改 for 循环变量的语义,Go1.21 新版本即可体验!》提到的 GOEXPERIMENT=loopvar 特性已经默认加到该版本。语法将默认改变。
// 运行第一次 2 3 1 4 5 // 运行第二次 2 3 1 5 4 // 运行第三次 5 1 2 3 4 ...很多面试官喜欢拿这个来做面试题。敲黑板了,请大家改一下面试题和答案了。
func main() { for i := range 7 { fmt.Println("煎鱼", i) } fmt.Println("煎鱼进脑子了!") }在老版本的 Go 中,会直接报如下错误:
$ go run demo.go # command-line-arguments ./demo.go:8:17: cannot range over 7 (untyped int constant)但在 Go1.22 起,支持了该功能特性。
煎鱼 0 煎鱼 1 煎鱼 2 煎鱼 3 煎鱼 4 煎鱼 5 煎鱼 6 煎鱼进脑子了!算是补全一个 for 循环的小缺漏。