文章目录
1. 什么是defer
defer是Go语言提供的一种用于注册延迟调用的机制:让函数或语句可以在当前函数执行完毕后(包括通过return正常结束或者panic导致的异常结束)执行。
2. defer的应用场景
defer语句通常用于一些成对操作的场景:打开连接/关闭连接;加锁/释放锁;打开文件/关闭文件等。
3. defer的实现原理
defer语句并不会马上执行,而是会进入一个栈,函数return前,会按先进后出(FILO)的顺序执行。也就是说最先被定义的defer语句最后执行。先进后出的原因是后面定义的函数可能会依赖前面的资源,自然要先执行;否则,如果前面先执行,那后面函数的依赖就没有了。
4. defer的引用方式
defer语句定义时,对外部变量的引用有如下两种方式:
- 作为函数参数和作为闭包引用。作为函数参数,则在defer定义时就把值传递给defer,并被缓存起来。
- 作为闭包引用的话,则会在defer函数真正调用时根据整个上下文确定当前的值。
5. defer的踩坑点
避免踩坑的关键是要理解这条语句:
return xxx
这条语句经过编译之后,会变成了三条指令:
1. 返回值 = xxx
2. 调用defer函数
3. 空的return
第1,3 步才是return 语句真正的命令,第2步是 defer的定义语句,这里就有可能会操作返回值。
6. 代码示例
6.1 示例1
func f() (r int)