猿问

go 闭包问题

代码如下:
packagemain
import(
"fmt"
"sync"
"time"
)
vara=[...]int{1,2,3,4,5}
funcRun(){
fmt.Println("begin")
varwgsync.WaitGroup
wg.Add(len(a))
for_,i:=rangea{
/*gofunc(iint){//函数变量是以值的方式传递的
fmt.Printf("getvalue%d\n",i)
time.Sleep(time.Second)
wg.Done()
}(i)*/
gofunc(){
fmt.Printf("getvalue%d\n",i)
time.Sleep(time.Second)
wg.Done()
}()
}
wg.Wait()
fmt.Println("end")
}
funcmain(){
Run()
}
运行结果输出:begingetvalue5getvalue5getvalue5getvalue5getvalue5end
不给匿名函数传参的话,为什么只能获取最后一个值,其中原理还是想不太明白,请各位大哥给讲解下,谢谢!!!
慕运维8079593
浏览 332回答 2
2回答

狐的传说

你可以认为是调度问题有两点需要注意:i不是每次循环的局部变量,而是整个for块的全局变量,你的所有routine中的i引用的是同一个i新开routine是一个费时操作,而循环却非常快,所以还没有等到一个routine引用i,for循环就结束了,此时的i已经就是最后一个值了

长风秋雁

这是golang很经典的问题。当在循环中启动协程时,协程的启动一定不会跟循环同步。你闭包执行的值是什么取决于协程启动时循环到的位置。就像你的例子,当你的for循环完之后,你定义的go协程才启动执行,这个时候你的i值统一都是5.如果你当初参数传入,那么这个值就是是定义闭包时,循环到的值了。
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答