当前位置: 首页 > news >正文

go panic与error

go panic与error

panic 是 Go 的一种运行时错误报告机制,类似于其他语言中的“异常”,但设计哲学完全不同。调用 panic 会让程序立即停止当前函数的正常执行,并开始沿调用栈向上冒泡,依次执行每一层的 defer,最终如果没有被 recover 捕获,则导致程序崩溃并打印栈跟踪信息。

  • 由内置函数触发:panic("something wrong"),也可由运行时错误触发(如空指针、索引越界、类型断言失败)。

  • 不可恢复(默认):一旦触发,除非被 recover 拦截,否则程序必死。

  • 执行所有 defer:在向上传播过程中,当前函数及每一层调用者注册的 defer 都会按照 LIFO 顺序执行。

  • 只能由 recover 捕获:必须在 defer 中调用 recover() 才能捕获 panic,并恢复程序的控制流。

 

func safeCall() {defer func() {if r := recover(); r != nil {fmt.Println("Recovered from:", r)}}()doPanic()fmt.Println("This won't print")
}func doPanic() {panic("boom")
}func main() {safeCall()fmt.Println("Program continues")
}

结果

Recovered from: boom
Program continues

panic 会创建 _panic 结构体,挂在当前 goroutine 上,并立即执行该 goroutine 的 defer 链。当遇到 recover() 时,它会跳过当前的 _panic 并返回该 panic 的值。如果 recover 返回非 nil,则表明刚刚拦截了一个 panic,goroutine 恢复正常执行(从当前 defer 之后继续),但该 defer 所在函数的后续正常代码不会被执行(已经中断)。

 

  • recover 必须直接放在 defer 函数中,嵌套了就不行(如 defer func() { func() { recover() } }() 无效)。

  • 在一个 defer 里 recover 之后,后续的 defer 仍会正常执行。