关于闭包作用域的一个问题

来源:1-2 课程介绍

Echo鑫

2019-04-14

func B() []func() {
	b := make([]func(), 3, 3)
	for i := 0; i < 3; i++ {
		b[i] = func() {
			fmt.Println(i)
		}
	}
	return b
}

func main() {
	c := B()
	c[0]()
	c[1]()
	c[2]()
}
/*
**  输出:
**  3
**  3
**  3
*/

老师这是什么原因。。有点理解不透

写回答

1回答

xiaomo

2019-04-14

因为每次for循环时, 程序只是将匿名函数加到了切片中而并没有执行,此时引用的变量都是同一个变量i; 

所以随着循环后i的值改变,每个匿名函数里i也是跟着改变的;

循环结束后,i变成了3, 各个函数的i的值也变成了3。

可以这么解决:

func B() []func() {
        b := make([]func(), 3, 3)
        for i := 0; i < 3; i++ { // 每次循环i是相同的变量
                temp := i   // 赋值给临时变量temp, 每次循环temp是不同的变量
                b[temp] = func() {
                        fmt.Println(temp)
                }
        }
        return b
}
0
1
Echo鑫
非常感谢!
2019-04-14
共1条回复

Go实战仿百度云盘-实现企业级分布式云存储系统

紧随“云时代”技术潮流,分布式云存储系统,做第一代云程序员

1077 学习 · 494 问题

查看课程