package main
import "fmt"
func main() {
for i := 0; i < 3; i++ {
defer func() {
fmt.Println("a:", i)
}()
}
}
输出是:
a:3
a:3
a:3
package main
import "fmt"
func main() {
for i := 0; i < 3; i++ {
i := i
defer func() {
fmt.Println("a:", i)
}()
}
}
输出是:
a:2
a:1
a:0
为什么两个的运行结果会不一样呢?
1
zyqzyq08 2019-06-10 21:39:07 +08:00 via Android 1
闭包问题
|
2
gamexg 2019-06-10 21:43:11 +08:00
在循环结束时 defer 才会执行,
第一个输出的是 for 语句的 i 的值,这时候 i 已经是 3 了( (3<3)!=true,循环结束 )。 第二个输出的是局部变量 i,当然是 2、1、0. |
3
chy373180 2019-06-10 21:52:34 +08:00
|
5
liulaomo 2019-06-10 23:36:35 +08:00
两个关键点:
1. 所有循环步共享同一个循环变量 i 2. 延迟调用在循环之后(程序退出之前)执行 |
6
liulaomo 2019-06-10 23:37:53 +08:00
第二个例子中的左 i 和右 i (循环变量)不同,每个循环步有自己独立的左 i
|
7
j2gg0s 2019-06-10 23:38:15 +08:00
第一个只有一个变量;第二个有四个变量
|
8
hduwillsky 2019-06-11 07:06:32 +08:00 via iPhone
闭包是引用传值
|
9
zhyl 2019-06-11 08:41:10 +08:00 via Android
第二个循环中每次都会定义 i,闭包中引用的是每次新定义的 i 的值,依次是 0 1 2,defer 先入后出打印出来就是 2 1 0
|
10
beidounanxizi 2019-06-13 12:36:41 +08:00 via iPhone
闭包传值问题。go 是按值传递,参见 https://github.com/golang/go/wiki/CommonMistakes
|
11
beidounanxizi 2019-06-13 12:38:12 +08:00 via iPhone
@hduwillsky go 只有按值传递,没有引用传值,有值类型和引用类型,楼主的问题是 loop goroutime 的执行问题
|