typora/note/Go/崩溃恢复.md
2024-12-12 10:48:55 +08:00

65 lines
2.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 带来的性能损耗