先来看一段golang 1.22版本之前的for循环的代码
package main
import "fmt"
func main() {
done := make(chan bool)
values := []string{"chen", "hai", "feng"}
for _, v := range values {
fmt.Println("start")
go func() {
fmt.Println(v)
done <- true
}()
fmt.Println("end")
}
for _ = range values {
<-done
}
}
运行结果
输出的都是最后的"feng"
在for循环体里,匿名函数和循环变量v形成了闭包。循环变量v只会创建一次,每次迭代都会更新。而且这样的写法会导致for循环结束后才执行goroutine代码,这时候变量v里保存的是最后一个值,所以这里会输出"feng"。
以下提供两种常用的正确写法
第一种方法是在匿名函数中添加参数val,每个val都会被独立计算并保存到goroutine的栈中,所以可以达到预期的结果
package main
import "fmt"
func main() {
done := make(chan bool)
values := []string{"chen", "hai",