当Go语言for,range遇到闭包时候的坑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var ss [5]struct{}
//第一种情况,很正常,输出0,1,2,3,4
for i := range ss {
fmt.Println(i)
}
//第二种情况,典型的Go语言闭包,它捕获了变量i,但是要注意的是它持有的是引用不是拷贝,当for循环结束时,i=4
//所以闭包输出的结果都是4
for i := range ss {
defer func() {
fmt.Println(i)
}()
}
//第三种情况,这种情况下的闭包,它并没有捕获变量i,而是通过传参的方式,这种情况下它得到的是拷贝
//所以其结果是4,3,2,1,0
for i := range ss {
defer func(i int) {
fmt.Println(i)
}(i)
}