GO之旅(1)

46 篇文章 0 订阅
4 篇文章 0 订阅

package main

import (
	"fmt"
)

func main() {
	var fs = [4]func(){}

	for i := 0; i < 4; i++ {
		defer fmt.Println("defer i = ", i)
		defer func() { fmt.Println("defer_closure i=", i) }()
		fs[i] = func() { fmt.Println("closure i=", i) }
	}
	for _, f := range fs {
		f()
	}
}
该段代码的输出为:


解释一下输出的原因:

由于defer就像一个栈一样,所以前面的defer输出语句以及函数调用都是用栈存储起来最后输出,所以最先输出的是:

for _, f := range fs {
	f()
}
由于fs在之前的循环中都已经进行了赋值,所以会直接调用相应的函数,可是为什么答案不是输出0,1,2,3而是输出四个4呢?

原因很简单,是因为

fs[i] = func() { fmt.Println("closure i=", i) }
这个函数是个空名函数,由于并没有参数传进来,可是他要输出i,那么程序只有向外层查找i变量,然后记录下i的地址,需要用的时候再去输出,所以程序执行到最后的时候i的地址对应的值是4,所以就全部输出了4。

所以第一个for循环里面的defer函数也是同样的道理。

但是第一个for的defer直接输出语句,是因为输出函数里面的i是作为参数,有数值的拷贝过程,所以因此会输出0,1,2,3。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值