typora/note/Go/崩溃恢复.md

65 lines
2.0 KiB
Markdown
Raw Permalink Normal View History

2024-12-11 21:48:55 -05:00
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 带来的性能损耗