【发布时间】:2021-10-08 07:54:58
【问题描述】:
有人知道为什么 case1 输出相同的结果,而 case2 输出的是顺序结果吗? 我知道case1输出相同值的原因是函数中每个函数的闭包切片访问相同的范围。
但是为什么在每个循环中添加 i:=i 后 case2 可以输出顺序结果? 在每个循环中重新定义 i 之后,是否会生成一个新的范围? 像 let in javascript?
案例1
func main() {
funcs := []func() {}
for i:=0;i<10;i++{
funcs = append(funcs, func() {
fmt.Println(i)
})
}
for i:=0;i<10;i++{
funcs[i]()
}
}
输出
10
10
10
10
10
10
10
10
10
10
案例2
func main() {
funcs := []func() {}
for i:=0;i<10;i++{
i := i
funcs = append(funcs, func() {
fmt.Println(i)
})
}
for i:=0;i<10;i++{
funcs[i]()
}
}
输出
0
1
2
3
4
5
6
7
8
9
【问题讨论】:
-
Scope 是相关的,但在这里使用的术语是错误的。
i := i是一个简短声明,它创建一个新的i,所以是的,这有点像Javascript 中的let。但是,无论是否有内部声明,范围 都存在。后面对i的引用使用了可用的最内层范围i。如果没有简短的声明,那就是外部i;有了它,这就是内在的i。 -
这能回答你的问题吗? Captured Closure (for Loop Variable) in Go
-
非常感谢您的信息