
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 闭包问题 |
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 的执行问题 |