先看一段程序
package main
import (
"fmt"
)
func main() {
a := []int{1, 2, 3}
for _, i := range a {
fmt.Println(i)
defer p(i)
}
}
func p(i int) {
fmt.Println(i)
}
运行这段程序,输出结果为
1
2
3
3
2
1
这里就是普通的函数调用,每次调用func p时,完成 i 的值复制,然后打印,此时 i 值复制了3次,分别是1,2,3。由于defer是后进先出,所以执行变成3,2,1
下面我我们用闭包改写下程序:
package main
import (
"fmt"
)
func main() {
a := []int{1, 2, 3}
for _, i := range a {
fmt.Println(i)
defer func() {
fmt.Println(i)
}()
}
}
运行这段程序,输出结果为
1
2
3
3
3
3
这个就是闭包的“神奇”之处。闭包里的非传递参数外部变量值是传引用的,在闭包函数里那个i就是外部非闭包函数自己的参数,所以是相当于引用了外部的变量, i 的值执行到第三次是3 ,闭包是地址引用所以打印了3次i地址指向的值,所以是3,3,3