当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《为什么局部变量是goroutine中匿名函数的不同参数》经验,为你挑选了1个好方法。

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

您当前的输出是这样的:

1 100
2 100
3 100
4 100
...

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

当调度程序开始执行你的goroutine时,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
...

这种现象并不孤立于Go.

你可以在操场上看到一个工作样本: View it on the Playground



1> Simon Whiteh..:

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

您当前的输出是这样的:

1 100
2 100
3 100
4 100
...

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

当调度程序开始执行你的goroutine时,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
...

这种现象并不孤立于Go.

你可以在操场上看到一个工作样本: View it on the Playground

推荐阅读
手机用户2502851955
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有