在 Golang 中,defer、panic 和 recover 三个关键词关系密切,用于异常处理机制。
- defer: defer 语句会将其后面跟随的语句进行延迟执行。在函数结束的时候,这些延迟调用的语句将按照逆序执行。defer 主要用于资源清理、文件关闭、解锁等操作。
- panic: panic 可以在程序运行过程中引发一个异常,默认会终止当前运行goroutine。通常用于不可恢复的错误。
- recover: recover 允许程序员控制一个panic,并恢复正常的执行。recover 只在defer调用的函数中有效。
他们的关系可以总结为:
defer statement 可以跟一个 panic 的recover语句一起使用,以允许panic被恢复。
如果没有recover语句与该defer一起使用,panic将继续通过调用栈传播。
示例代码:
func test() {
defer func() {
if err := recover(); err != nil {
fmt.Println("recover in defer")
}
}()
panic("panic in test()")
}
func main() {
test()
fmt.Println("main")
}
输出:
recover in defer
main
可以看到,由于在 defer 中使用了 recover 捕获了 panic,所以程序并未退出,而是继续运行,并输出 main。
如果去掉 defer 中的 recover,则程序运行 panic 后会退出,不会输出 main。
所以总结来说,三者关系是:
- defer 用于延迟执行(资源清理等),并可以搭配 recover 捕获 panic
- panic 主动触发异常,如果未被 recover 捕获,会退出程序
- recover 用于捕获 panic,恢复正常程序执行