gpt4 book ai didi

go - 为什么局部变量在goroutine中的匿名函数中是不同的参数

转载 作者:IT王子 更新时间:2023-10-29 01:33:24 33 4
gpt4 key购买 nike

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()
}

我只是想知道为什么 n 不等于 i 每个 go 例程。

此外,i 有时与上一次调用具有相同的值。

这段代码有什么问题?

最佳答案

这个主题涵盖得很好(跨多种语言)——但简短的版本是这样的:

你当前的输出是这样的:

1 100
2 100
3 100
4 100
...

变量 i 成为闭包的一部分。这意味着它的值实际上超出了它的范围(它移到了一边,这样当 goroutine 执行时它知道在哪里可以找到 i)。

当调度器开始执行你的 goroutines 时,for 循环已经完成并且 i 的值将是 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)
}

现在每个 goroutine 引用它自己的封闭变量 x 的副本,你的输出变成:

1 1
2 2
3 3
4 4
...

这种现象并非围棋独有。

你可以在 playground 上看到一个工作示例: View it on the Playground

关于go - 为什么局部变量在goroutine中的匿名函数中是不同的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34080050/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com