Go panic

本文将介绍 Go 中的 panic、recover 及注意事项。

一、panic - 宕机

panic,宕机,是指 Go 程序运行时出现的严重错误。

在 Go 中,panic 主要有两类来源:

  • 运行时 panic,例如数组越界、空指针访问等
  • 显式调用 panic() 函数主动触发

一旦 panic 触发,后续将会进行 panicking,具体来说:

  • 函数执行终止
  • 执行 defer 命令
  • 回退至函数调用处,继续重复 1、2 步骤,直至执行栈为空
  • 整个程序异常退出

二、recover - 恢复

recover() 是一个内建函数,用于避免宕机,它能够恢复处于 panicking 状态的 goroutine。

需要注意的是:

  • recover() 仅在 defer 命令中有效
  • 如果 goroutine 处于 panicking 状态,则 recover() 的返回值为错误值,否则为 nil

三、注意事项

1. 可以通过 recover() 确保程序的持续运行

如果程序的持续运行非常重要,则必须用 recover() 捕捉并恢复

例如 HTTP 服务,不应该因为处理某一个请求的 goroutine 出现 panic 导致整个 HTTP 服务崩溃

2. panic / recover 不等同于 try catch

如果有过 Java 语言编程经验,很可能将 panic / recover 当做 try catch 使用,这是违反 Go 设计准则的。

具体来说:

  • 对于可以预见的错误,
    • 在 Java 中,它对应 Checked 异常,通过 try...catchthrows 处理
    • 在 Go 中,它对应错误,应该用 函数返回值 + error 处理
  • 对于不可预见的、运行时错误,
    • 在 Java 中,它对应 Runtime 异常,可以选择处理也可以选择不处理
    • 在 Go 中,它对应 panic

参考