Go的panic、defer、recover的关系
前置说明:go 没有
try/catch机制
defer的作用是无论函数如何退出(正常 return / panic),都确保某些代码运行, 并且defer 只能写在函数内recover()只是一个普通函数 ,但它有个特殊能力:只有在defer中调用时,才能"拦截"当前 goroutine 的 panic。
当 panic 发生时,Go 运行时会做以下事情:
- 立即停止当前函数的后续代码执行 (
panic之后的语句不会跑)。 - 开始逆序执行当前 goroutine 栈上所有已注册的
defer函数(LIFO 顺序)。 - 在 defer 函数中,你可以选择:
- 什么都不做 → panic 继续向上传播,最终程序崩溃。
- 调用
recover()→ 如果成功,panic 被"吃掉",程序恢复正常执行。
🌟 所以:
defer是 panic 传播路径上的"检查站",而recover是检查站里的"灭火器"。
go
package main
import "fmt"
func main() {
defer fmt.Println("Deferred: cleanup done")
defer func() {
fmt.Println("Deferred: logging error")
}()
defer func() {
if err := recover(); err != nil {
fmt.Println("Recovered from panic:", err)
}
}()
panic("Oops!")
}