重点:
1、defer和go一样都是Go语言提供的关键字。defer用于资源的释放,会在函数返回之前进行调用。
2、如果有多个defer表达式,调用顺序类似于栈,越后面的defer表达式越先被调用。
3、defer是在return之前执行的。
package main
import "fmt"
func main() {
f()
}
func f() (result int) {
defer func() {
result += 5
fmt.Println("defer 1 :", result)
}()
defer func() {
result = result * 3
fmt.Println("defer 2 :", result)
}()
defer func() {
result = result - 50
fmt.Println("defer 3 :", result)
}()
return 0
// 这样的函数执行过程:先给0赋值0,然后倒序调用defer 函数 ,最后return。
// 本质原因:return xxx不是一条原子指令,而是 赋值 + return 指令的结合
}
输出:
defer 3 : -50 // 最后一个defer先被调用
defer 2 : -150
defer 1 : -145
defer表达式可能会在设置函数返回值之后,在返回到调用函数之前,修改返回值,使最终的函数返回值与你想象的不一致。
其实使用defer时,用一个简单的转换规则改写一下,就不会迷糊了。改写规则是将return语句拆成两句写,return xxx会被改写成:
返回值 = xxx
调用defer函数
空的return