为什么局部变量在goroutine的匿名函数中是不同的参数 主程序包 进口( “fmt” “运行时” ) func main(){ runtime.GOMAXPROCS(runtime.numpu()) fmt.Println(runtime.GOMAXPROCS(0)) //s:=“你好,世界”\n 对于i:=0;i

为什么局部变量在goroutine的匿名函数中是不同的参数 主程序包 进口( “fmt” “运行时” ) func main(){ runtime.GOMAXPROCS(runtime.numpu()) fmt.Println(runtime.GOMAXPROCS(0)) //s:=“你好,世界”\n 对于i:=0;i,go,goroutine,Go,Goroutine,我只是想知道为什么n不等于I每个围棋程序 另外,i有时与上一次调用中的值相同 这段代码中有什么问题?这个主题已经很好地涵盖了(跨多种语言)-但简短的版本是: 您当前的输出如下所示: package main import ( "fmt" "runtime" ) func main() { runtime.GOMAXPROCS(runtime.NumCPU()) fmt.Println(runtime.GOMAXPROCS(0)) // s := "hello world

我只是想知道为什么
n
不等于
I
每个围棋程序

另外,
i
有时与上一次调用中的值相同


这段代码中有什么问题?

这个主题已经很好地涵盖了(跨多种语言)-但简短的版本是:

您当前的输出如下所示:

package main

import (
  "fmt"
  "runtime"
)

func main() {
  runtime.GOMAXPROCS(runtime.NumCPU())
  fmt.Println(runtime.GOMAXPROCS(0))

  // s := "hello world \n"

  for i := 0; i < 100; i++ {
    go func(n int) {
        fmt.Println(n, i)
    }(i)
  }

  fmt.Scanln()
}
变量
i
成为闭包的一部分。这意味着它的值实际上超过了它的作用域(它移到了一边,这样当goroutine执行时,它知道在哪里可以找到
i

当调度程序开始执行goroutines时,for的
循环已经完成,
i
的值将为100(如果在低速机器上运行,则接近于100)

解决方法是在每次迭代中存储值并使用:

1 100
2 100
3 100
4 100
...
这种现象并不是孤立的

您可以在操场上看到一个工作示例:

for i := 0; i < 100; i++ {
    x := i            // <------ Store the value of i each loop iteration
    go func(n int) {
        fmt.Println(n, x) // <---- Use the new, local, closed over value, not the main closed over one
    }(i)
} 
1 1
2 2
3 3
4 4
...