goroutine与循环变量的坑

我们在使用goroutine的时候有在需要对循环数据并发执行的时候,有可能会写下如下代码

func main() {

   wg := sync.WaitGroup{}

   arr := []int{1, 2, 3, 4}

   for _, item := range arr {

      wg.Add(1)

      go func() {

         fmt.Println(item)

         wg.Done()

      }()

   }

   wg.Wait()

}

打印:

4

4

4

4

这是因为闭包中的变量 item 是在循环中被复用的,而不是在每次迭代中被捕获。这导致了所有的 Goroutine 共享同一个

item 变量,最终它们都会打印出循环结束时的 item 值。

如果要解决这个问题有3种方案

1.go的版本升级到1.22每次循环都会有自己的变量

2.为每次迭代创建一个变量

for _, item := range arr {

   tmp := item //创建一个临时变量

   wg.Add(1)

   go func() {

      fmt.Println(tmp)

      wg.Done()

   }()

}

3.不在依赖闭包,而是使用实际函数

for _, item := range arr {

   wg.Add(1)

   go func(val int) { //创建一个为整型的实际

      fmt.Println(val)

      wg.Done()

   }(item)

}

 


在线交流