defer
用于延迟函数的调用,常用于关闭文件或者关闭锁的场景。
defer语句采用类似栈的方式,每遇到一个defer就会把defer后面的函数压入栈中,在函数返回前再把栈中的函数依次取出执行。
一般函数正常返回时会执行被defer延迟的函数,特别的遇到return和panic时也会触发延迟函数。
defer作用于资源释放(关闭文件句柄、数据库连接、停止定时器ticker以及关闭管道)、流程控制(控制函数执行顺序,如wait.Group)和异常处理(recover()),但是defer关键字只能作用于函数或者函数调用。
三条defer的行为规则:
- 延迟函数的参数在defer语句出现时就已经确定了
- 延迟函数按后进先出LIFO的顺序执行,即先出现的defer最后执行
- 难点 延迟函数可能操作住函数的具体变量名称返回值,4种情况依次讲解:
(1). 函数返回过程
func deferFuncReturn() (res int) {
i := 1
defer func() {
res++
}()
return i
}
需要知道的是return不是一个原子操作,其分为两步执行,先将i放入栈中作为返回值,然后再进行跳转,而defer的执行正好是在跳转之前,所以defer执行时是有机会操作返回值的。
return语句可以翻译成