结论
defer
是在函数代码体执行完之后,函数返回之前执行的,多个 defer
之间按照后进先出(LIFO)的顺序执行。
这里还有个问题需要说明,return
并非原子操作,所以在有 defer
的情况下,函数的执行分为4个阶段,分别如下:
- 真正的函数体执行业务逻辑
- 函数返回值赋值,就是将真正的函数体执行结果赋值给返回值
defer
函数要执行的业务逻辑,注意这里 defer
中函数处理中有可能会修改返回值
- 执行
return
整个函数调用栈结束
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package main
import "fmt"
func f1() int { x := 5 fmt.Println("set value") defer func() { x++ fmt.Println("defer") }() return x }
func main() { fmt.Println(f1()) }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| package main
import "fmt"
func f2() (x int) { fmt.Println("set value") defer func() { x++ fmt.Println("defer") }() return 5 }
func main() { fmt.Println(f1()) }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package main
import "fmt"
func f3() (x int) { fmt.Println("set value") defer func(x int) { x++ fmt.Printf("defer") }(x) fmt.Printf("func") return 5 }
func main() { fmt.Println(f1()) }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| package main
import "fmt"
func f4() (x int) { defer func(x *int) { *x++ fmt.Printf("defer:%v\n", &x) }(&x) fmt.Printf("func:%v\n", &x) return 5 }
func main() { fmt.Println(f4()) }
|