在 Go 语言中,panic 和 recover 是用于处理程序中严重错误的机制,它们不是常规的错误处理方式(应使用 error 返回值),而是用于处理那些本不应该发生、或程序无法继续正常执行的异常情况。
panic 是 Go 提供的一个内置函数,用于主动触发一个运行时恐慌(panic),导致程序停止当前函数的执行,并开始**向上回溯(unwind)**调用栈。
package main
import "fmt"
func badFunction() {
panic("oh no! something terrible happened")
fmt.Println("This will not be printed")
}
func main() {
fmt.Println("Start")
badFunction()
fmt.Println("End") // 不会执行
}输出:
Start
panic: oh no! something terrible happened
goroutine 1 [running]:
main.badFunction()
...
main.main()
...recover 是一个内置函数,用于捕获 panic 并恢复正常执行。它只能在 defer 函数中有效。
package main
import "fmt"
func safeDivide(a, b int) int {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from panic:", r)
}
}()
if b == 0 {
panic("division by zero")
}
return a / b
}
func main() {
fmt.Println("Start")
result := safeDivide(10, 0) // 触发 panic,但被 recover 捕获
fmt.Println("Result:", result) // 会执行,result 为 0(未赋值)
fmt.Println("End")
}
输出:
Start
Recovered from panic: division by zero
Result: 0
End虽然 Go 鼓励使用 error 作为主要错误处理方式,但 panic/recover 在以下场景中是合理的:
特性 | panic | recover |
作用 | 触发异常,中断执行 | 捕获 panic,恢复执行 |
调用位置 | 任意地方 | 只能在 defer 函数中 |
返回值 | 无 | interface{},一般是错误信息 |
是否必须 | 否 | 否(但用于防止程序崩溃) |
推荐用途 | 不可恢复错误、程序逻辑错误 | 全局错误处理、保护关键函数 |
记住:Go 的哲学是“显式错误处理”,优先使用 if err != nil,panic/recover 是最后的手段。