Go协程闭包的问题
问题 最近在代码中遇到了这么一个问题,现在有一个循环,每一个循环中创建一个协程用来执行函数,我发现函数运行的结果却是大部分时候都是使用最后一个循环变量,不符合实际要求。 大概的代码如下: package main import ( "fmt" "net/http" ) func main() { for i := 0; i < 10; i++ { go func() { fmt.Println(i) }() } http.ListenAndServe(":8080", nil) } 运行: 10 10 10 10 10 10 10 10 10 10 多次运行,可以发现大部分情况都是将 i = 10 代入函数执行。 原因 那这是为什么呢? 这个就是函数闭包。协程运行的是一个闭包函数,其中使用了主线程的变量i 。看上去这和第一组几乎一样。但是在每个协程中,从进入匿名函数到调用Println将i的值复制入栈之间仍需要一小段时间运行,而这段时间内足以主线程完成全部10次循环。所以终于到将i的值复制入栈调用Println时,i已经成为10且不再变化了。 解决 那该怎么解决使代码如我们的需求运行呢? 我们只需将变量 i 复制进栈中即可,改动后的代码: package main import ( "fmt" "net/http" ) func main() { for i := 0; i < 10; i++ { go func(j int) { fmt.Println(j) }(i) } http.ListenAndServe(":8080", nil) } 结果: ...