跳转到主内容
极星编程网:以代码为星,赴技术山海!

Go语言recover使用注意事项_Golang panic恢复限制说明

recover 只在 defer 函数内部直接调用才有效,必须先注册 defer 再 panic;无法捕获子 goroutine 的 panic;recover 后不可继续业务逻辑,仅用于记录日志和安全退出。 recover 只在 defer 函数内部直接调用才有效,其他任何写法都返回 nil —— 这不是 bug,是 Go 的确定性设计。 recover 必须写在 defer 匿名函数里,且 defer 要在 panic 前注册 常见错误是把
recover()
放在普通代码块、
if
分支或
panic()
后面,这些位置根本不会执行,或执行时 panic 已结束。 ❌ 错误:
func f() { panic("x"); r := recover() }
——
recover()
永远执行不到 ❌ 错误:
func f() { panic("x"); defer func() { r := recover() }() }
——
defer
在 panic 之后注册,已失效 ✅ 正确:
func f() { defer func() { if r := recover(); r != nil { log.Print(r) } }(); panic("x") }
——
defer
先注册,
recover()
在其内部直接调用 recover 无法捕获子 goroutine 的 panic 每个 goroutine 有独立的 panic/recover 作用域。主线程写了
defer
+
recover
,对
go func() { panic("x") }()
完全无效 —— 子 goroutine 会静默崩溃,主 goroutine 继续运行,你收不到任何通知。 HTTP worker 池中,每个 worker 必须自带
defer func() { recover() }()
,不能指望中间件统一兜底 封装
safeGo(f)
启动协程时,
f
内部仍需自己加
defer
,否则没用 没有“全局 recover”机制,跨 goroutine 捕获是语言层面不支持的 recover 后不能继续业务逻辑,状态大概率已损坏
recover()
成功只意味着 goroutine 不退出,它不回滚任何副作用,也不修复变量、锁、channel 或文件句柄状态。 go语言参考手册 中文CHM版 Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。本文给大家带来Go参考手册,需要的可以来下载! Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。 Go 语言特色 简洁、快速、安全 并行、有趣、开源 内存管理、v数组安全、编译 下载 立即学习 “ go语言免费学习笔记(深入) ”; panic 前可能已部分更新结构体字段、解引用空指针、向已关闭 channel 写入 —— 这些破坏不可逆 不要在
recover
分支里调用 DB 写入、HTTP 请求、或依赖局部变量的函数 合理做法:记录 panic 栈和 request ID → 返回 500 或 fallback 响应 → 显式
return
或清理后退出当前任务 最易被忽略的一点:recover 不是 error 替代品,也不是事务回滚工具;它只提供一次“软着陆”机会,用错比不用更危险。

相关文章