简介
对于老版本的for循环使用,有一个很经典的bug,就是每次循环的变量其实是同一个,后面的循环会更新覆盖前面变量的值。在发布的1.22版本中,修改成了每次迭代都创建新的变量,来规避之前并发情况下可能存在的问题;另外一个特性是支持整数类型直接for循环。
示例
老版本(1.22之前)
之前的版本,go func(){}中打印的v变量结果都是c,也就for循环最后那次变量的值。
[xiaofeng@localhost gostudy]$ go version
go version go1.18.4 linux/amd64
[xiaofeng@localhost gostudy]$
[xiaofeng@localhost gostudy]$ cat main.go
package main
import "fmt"
func main() {
done := make(chan bool)
values := []string{"a", "b", "c"}
for _, v := range values {
go func() {
fmt.Println(v)
done <- true
}()
}
// wait for all goroutines to complete before exiting
for _ = range values {
<-done
}
}
[xiaofeng@localhost gostudy]$
[xiaofeng@localhost gostudy]$ go build main.go
[xiaofeng@localhost gostudy]$
[xiaofeng@localhost gostudy]$ ./main
c
c
c
[xiaofeng@localhost gostudy]$
处理方法也都是通过给go func(){}传参,打印的变量值结果是c、a、b(顺序随机是因为go func启动执行动态调度导致)。
[xiaofeng@localhost gostudy]$ cat main.go
package main
import "fmt"
func main() {
done := make(chan bool)
values := []string{"a", "b", "c"}
for _, v := range values {
go func(vp string) {
fmt.Println(vp)
done <- true
}(v)
}
// wait for all goroutines to complete before exiting
for _ = range values {
<-done
}
}
[xiaofeng@localhost gostudy]$
[xiaofeng@localhost gostudy]$ go build main.go
[xiaofeng@localhost gostudy]$
[xiaofeng@localhost gostudy]$ ./main
c
a
b
新版本
升级(使用root)
更新go版本到1.22.1。
[root@localhost Go]# wget https://golang.google.cn/dl/go1.22.1.linux-amd64.tar.gz
[root@localhost Go]# rm -rf /usr/local/go && tar -C /usr/local -xzf go1.22.1.linux-amd64.tar.gz
[root@localhost Go]# go version
go version go1.22.1 linux/amd64
验证变量特性
此时直接for循环,在go func(){}中打印的不再全是c,而是每次循环分别的值。
[root@localhost gostudy]# go version
go version go1.22.1 linux/amd64
[root@localhost gostudy]#
[root@localhost gostudy]# cat main.go
package main
import "fmt"
func main() {
done := make(chan bool)
values := []string{"a", "b", "c"}
for _, v := range values {
go func() {
fmt.Println(v)
done <- true
}()
}
// wait for all goroutines to complete before exiting
for _ = range values {
<-done
}
}
[root@localhost gostudy]#
[root@localhost gostudy]# go build main.go
[root@localhost gostudy]#
[root@localhost gostudy]# ./main
c
a
b
支持整型类型
另外,新版本支持整型类型进行for循环;而且是从0开始。
[root@localhost gostudy]# cat main.go
package main
import "fmt"
func main() {
for i := range 3 {
fmt.Println(i)
}
}
[root@localhost gostudy]#
[root@localhost gostudy]# go build main.go
[root@localhost gostudy]#
[root@localhost gostudy]#
[root@localhost gostudy]# ./main
0
1
2