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

Iterating using a goroutine is giving unexpected result

我在 goroutine 中根据迭代变量 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

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

Playground example

你的所有 goroutines 运行 异步在你的 for 循环完成后

在你的 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.

这样你 "save" 函数内部 i 的值你告诉 goroutine 执行这样稍后,当 for 循环有 运行 完成时,它不会不要使用 i 当前 值,即 6;相反,它使用创建 goroutine 时 iold 值。