今天写代码的时候用到了协程go func
,发现func函数块内部的代码也能使用外部的局部变量,当时我就加上了打印发现闭包内部的变量值和外部的局部变量是一样的,就觉得很费解匿名函数的传参是什么用的?
然后我就做了个小实验,运行如下代码
func main() { i := 1 go func() { time.Sleep(100*time.Millisecond) fmt.Println("i =", i) } () i++ time.Sleep(1000*time.Millisecond) }
打印如下
i= 2 Process finished with exit code 0
这就说明了闭包内取外部函数的参数的时候是取的地址,而不是调用闭包时刻的参数值.我们通过如下代码验证我们的想法:
func main() { i := 1 go func(i int) { time.Sleep(100*time.Millisecond) fmt.Println("i =", i) } (i) i++ time.Sleep(1000*time.Millisecond) }
输出为:
i = 1 Process finished with exit code 0
所以我们在使用go func
的时候最好把可能改变的值通过值传递的方式传入到闭包之中,避免在协程运行的时候参数值改变导致结果不可预期
作者:cbsfly_
链接:https://www.jianshu.com/p/91140fdd6e91