https://mp.weixin.qq.com/s/ZmfwNlq5_A2RgpUSkJQXrQ ### defer - Go 语言提供的一种延迟调用机制,defer 的运作离不开函数 - 只有在函数(和方法)内部才能使用 defer - defer 关键字后面只能接函数(或方法),这些函数被称为 deferred 函数 - defer 将它们注册到其所在 Goroutine 中,用于存放 deferred 函数的栈数据结构中,这些 deferred 函数将在执行 defer 的函数退出前,按后进先出(LIFO)的顺序被程序调度执行 - 无论是执行到函数体尾部返回,还是在某个错误处理分支显式 return,又或是出现 panic,已经存储到 deferred 函数栈中的函数,都会被调度执行 ![](https://blog-heysq-1255479807.cos.ap-beijing.myqcloud.com/blog/wiki/go/defer.jpg) ![](blog-heysq-1255479807.cos.ap-beijing.myqcloud.com/blog/wiki/go/defer.jpg) blog-heysq-1255479807.cos.ap-beijing.myqcloud.com/blog/2023-12-11-xoomgtcr.png ### defer 注意事项 - 明确哪些函数可以作为 deferred 函数,有返回值的deferred函数的返回值会被自动丢弃 - 内置函数 append、cap、len、make、new和imag不能被注册为deferred函数,可以包装一层func,进行调用 - close、copy、delete、print、recover 可以被注册为deferred函数 ```go Functions: 内置函数列表 append cap close complex copy delete imag len make new panic print println real recover ``` - 注意 defer 关键字后面表达式的求值时机,defer 关键字后面的表达式,是在将 deferred 函数注册到 deferred 函数栈的时候进行求值的 ```go package main import ( "fmt" ) func foo1() { for i := 0; i <= 3; i++ { defer fmt.Println(i) } } func foo2() { for i := 0; i <= 3; i++ { defer func(n int) { fmt.Println(n) }(i) } } func foo3() { for i := 0; i <= 3; i++ { defer func() { fmt.Println(i) }() } } func main() { fmt.Println("foo1 result:") foo1() fmt.Println("\nfoo2 result:") foo2() fmt.Println("\nfoo3 result:") foo3() } ``` - 知晓 defer 带来的性能损耗