不再共享循环变量
在老版本的 Go 中,for 循环迭代器的变量是一个单一变量,在每个循环迭代中仅是取值不同。这样做在性能上非常高效,但如果使用不当,会导致意想不到的行为,可能会造成共享循环变量的问题。
最经典的场景就是在 goroutine 循环时的问题。如下代码:
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 的代码来再次赋值。经典的很。