我不明白为什么跟随程序打印0 1 2
。我以为会打印2 2 2
。
package main
import (
"fmt"
)
func main() {
var funcs []func()
for i := 0; i < 3; i++ {
idx := i
funcs = append(funcs, func() { fmt.Println(idx) })
}
for _, f := range funcs {
f()
}
}
我应该打印2 2 2
的原因是for循环的每次运行都共享相同的范围(例如,for循环的第二次运行不会终止第一次运行的范围,范围是共享的)。因此,idx的引用由for循环的每次运行中创建的匿名函数共享。因此,当循环结束时,创建的所有3个函数共享idx的相同引用,其值为2.
所以我认为这个问题归结为:for循环的新运行(例如,i == 2)是否结束了for循环的最后一次运行(例如,i == 1)的范围?如果答案能指向golang spec,我将不胜感激。 (我找不到提到这个的规格。)
答案 0 :(得分:2)
来自规范https://golang.org/ref/spec#For_statements
A&#34; for&#34; statement指定重复执行一个块。
每个块都有自己的范围,它们不是嵌套的或共享的。但是
每个&#34; if&#34;,&#34; for&#34;,&#34;&#34; switch&#34;声明被认为是在其中 拥有隐含的阻止。
您的代码段中的变量i是共享的
for i := 0; i < 3; i++ {
funcs = append(funcs, func() { fmt.Println(i) })
}
for _, f := range funcs {
f()
}
将按预期打印3 3 3。