Golang defer与闭包
引入
先来看俩程序
1 | package main |
1 | // 闭包状态下 |
这俩个程序区别在于一个直接调用输出,一个闭包输出,但结果却天差地别,下面深入了解下defer与闭包的关系
(PS:答案写在后记里了 :)
defer介绍
defer特性
- 关键字 defer 用于注册延迟调用。
- 这些调用直到 return 前才被执。因此,可以用来做资源清理。
- 多个defer语句,按先进后出的方式执行。
- defer语句中的变量,在defer声明时就决定了。
defer用途
- 关闭文件句柄
- 锁资源释放
- 数据库连接释放
defer执行顺序
定义defer的时,会先将defer后面的调用的函数的参数入栈,在return右侧的参数或函数值计算完成后调用defer,此时defer的函数参数出栈执行,defer执行完成后执行return
例子
例题一
1 | package main |
1 | package main |
例题二
1 | package main |
1 | package main |
在定义defer的时候,就要将defer后面的函数参数等入栈,等到return之前的时候出栈执行,a方法中是将i的拷贝直接入栈,b方法中通过一个闭包调用,实际上将i的指针传递给闭包,闭包读取值拷贝给add。
后记
回到一开始给出的两个程序,首先我们应该清楚for-range循环中i的地址是保持不变的,在非闭包的情况下,将值压入栈中进行保存,所以最后输出顺序为4 3 2 1 0,但在闭包条件下,右侧函数参数为空,i保存的为for中i的地址,由于i的值一直在改变,所以最后调用时打印出来的值均为最后的值4,即:4 4 4 4 4
参考文章:
评论
评论插件加载失败
正在加载评论插件