【问题标题】:strange behaviour of goroutines in for loop [duplicate]for循环中goroutines的奇怪行为[重复]
【发布时间】:2021-01-25 05:02:36
【问题描述】:

我正在从 Python 切换到 GoLang。我正在学习 goroutines。当我在 for 循环中使用 goroutine 时,我遇到了奇怪的输出。

package main

import "fmt"

func main() {
    var test = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
        28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40}
    for _, x := range test{
        go func() {
            fmt.Println(x)
        }()
    }
}

输出:

25
19
28
19
40
40
6

我以为它是从 for 循环中捕获值,但是当我看到它在增加和减少时。我很困惑。为什么会这样?

【问题讨论】:

  • @Marc 我不认为这个问题是一个非常准确的重复。它确实有一些重叠,因为这两个问题都是关于 for 循环中变量的范围和生命周期,但是 goroutine 版本没有明确使用 address-of 运算符,而且这并不明显(如果你还不知道关于语言的一点点),goroutines 在创建时不会复制堆栈变量。不过可能有更好的副本,因为这是一个常见的问题。

标签: for-loop go goroutine


【解决方案1】:

goroutine 正在访问x 变量,该变量与 goroutine 的执行并行更改。这是我认为即使是去程序员至少一次也会遇到的常见问题。您可以像这样捕获变量的当前值:

for _, x := range test{
    go func(x int) {
        fmt.Println(x)
    }(x)
 }

或者像这样:

for _, x := range test{
    x2 := x
    go func() {
        fmt.Println(x2)
    }()
 }

【讨论】:

  • 我很理解它可以从循环中随机选择值,但不明白为什么它会减少。
猜你喜欢
  • 1970-01-01
  • 2019-02-11
  • 1970-01-01
  • 1970-01-01
  • 2015-06-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多