前言
最近发现一个问题,一般来说recover是用来捕获异常防止程序挂了,也有说是复活甲,当遇到panic时会被捕获并记录,如下:
func myFunc() {
// 在函数体中的任何位置注册 defer
defer func() {
if r := recover(); r != nil {
// 处理 panic
fmt.Println("Recovered from panic:", r)
}
}()
// 函数逻辑
fmt.Println("Before panic")
panic("Oops! Something went wrong")
fmt.Println("After panic") // 这行代码不会被执行
}
打印:
Before panic
Recovered from panic: Oops! Something went wrong
如果去掉deffer func,则打印报错从而导致代码死机
Before panic
panic: Oops! Something went wrong
goroutine 1 [running]:
main.main()
/tmp/sandbox3398061893/prog.go:11 +0x5f
问题
deffer的位置很重要,因为如果在某个方法panic之后,deffer是不会被执行的。
deffer的原本作用:
在 Go 语言中,defer 关键字用于延迟(defer)指定函数或方法的执行,使其在所处函数退出之前(包括正常执行结束、return 返回)必定被执行
但这其中就有误区,如果deffer之前有panic就不会被执行,所以对于panic,一定最好放执行方法第一行,不然逻辑再多一些,如嵌套方法啥的,报错自己找吐估计都难发现为啥没生效!!!!!
代码如:
func main() {
// 函数逻辑
fmt.Println("Before panic")
panic("Oops! Something went wrong")
defer func() {
if r := recover(); r != nil {
// 处理 panic
fmt.Println("Recovered from panic:", r)
}
}()
fmt.Println("After panic")
}
依旧输出报错:
Before panic
panic: Oops! Something went wrong
goroutine 1 [running]:
main.main()
/tmp/sandbox3579129239/prog.go:11 +0x5f
我和AI对刚😂:
总结
以上是个人发现 ,defer 关键字用于延迟(defer)指定函数或方法的执行,使其在所处函数退出之前(包括正常执行结束、return 返回)必定被执行,但对于panic和recvoer需要看情况而定,建议还是放第一行来处理报错。如有不足,欢迎补充