如何使用Golang recover捕获panic_防止程序崩溃并处理异常

19次阅读

go语言用panic/recover+defer实现异常处理,recover仅在defer函数中有效且限于当前goroutine;需在易错逻辑外层封装safeRun等模式,子goroutine须独立加recover;recover后不继续执行panic点,仅恢复调度并返回。

如何使用Golang recover捕获panic_防止程序崩溃并处理异常

Go语言中没有传统意义上的try-catch机制,而是通过panicrecover配合defer来实现运行时异常的捕获与恢复。关键在于:recover只能在defer函数中调用才有效,且仅能捕获当前goroutine中的panic

recover必须配合defer使用

recover不是全局拦截器,它只在defer延迟执行的函数中调用时才起作用。如果写在普通逻辑里,返回值始终为nil,无法捕获任何panic。

  • 正确写法:在可能panic的函数内,先用defer注册一个匿名或命名函数,在其中调用recover()
  • 错误写法:把recover()放在if判断里、或者放在panic之后但不在defer中

典型安全封装模式

常见做法是将易出错逻辑包裹进一个带recover的闭包,统一处理异常:

func safeRun(f func()) {     defer func() {         if r := recover(); r != nil {             log.Printf("panic recovered: %v", r)             // 可记录日志、上报监控、返回默认值等         }     }()     f() }

调用方式:safeRun(func() { riskyOperation() })。这样即使riskyOperation触发panic,程序也不会退出,而是继续执行后续逻辑。

立即学习go语言免费学习笔记(深入)”;

注意goroutine隔离性

每个goroutine有独立的panic/recover作用域。主goroutine中defer的recover无法捕获子goroutine里的panic。

  • 子goroutine需自行加defer+recover,例如启动时就包装:go func() { defer safeRecover(); doWork() }()
  • http服务中,标准http.ServeMux已内置recover(如net/http包),但自定义handler仍建议手动加一层防护

recover后不能“继续执行”panic发生点

recover的作用是让程序从panic状态恢复正常调度,但它不会回到panic发生的那行代码继续执行。控制权会回到defer所在函数的末尾,然后按正常流程返回。

  • 例如:函数A中defer了recover,A内部某处panic → 执行defer函数 → recover成功 → A函数直接返回,不执行panic之后的代码
  • 因此,recover适合做“兜底清理”和“错误转化”,不适合用来“重试”或“修正错误后续跑完”

text=ZqhQzanResources