使用goroutine迭代会产生意想不到的结果

sco*_*ott 0 concurrency loops go goroutine

我在做一些条件基础上,iteratating变量够程内检查i,发现它是给我结果我没想到,我决定用一些简单的代码来确认.

    for i := 1; i <= 5; i++ {
    wg.Add(1)
    fmt.Println(i)

    go func() {
        fmt.Println(i)
        wg.Done()
    }()


}
wg.Wait()

1
2
3
4
5
6
6
6
6
6
Run Code Online (Sandbox Code Playgroud)

这是预期的行为吗?有人可以解释为什么6被打印5次,虽然我只迭代到5?

m0m*_*eni 5

游乐场的例子

for循环结束后,所有goroutine都以异步方式运行.

在你的for循环结束时i等于6,因此,你的goroutines每个都记录数字6.

要解决此问题,您可以创建一个闭包,并保存其中的当前值,i以便在运行goroutine时,它以正确的值运行i.

要做到这一点,只需更改代码即可

go func(x int) {
  fmt.Println(x)
  wg.Done()
}(i) // <--- "save" value of i at this point in time.
Run Code Online (Sandbox Code Playgroud)

这样你就可以"保存" i你告诉goroutine执行的函数内部的值,以便稍后,当for循环运行完成时,它不使用当前值为i6; 相反,它使用创建goroutine时的i.