recover 只在 defer 函数内部直接调用才有效,必须先注册 defer 再 panic;无法捕获子 goroutine 的 panic;recover 后不可继续业务逻辑,仅用于记录日志和安全退出。
recover 只在 defer 函数内部直接调用才有效,其他任何写法都返回 nil —— 这不是 bug,是 Go 的确定性设计。
recover 必须写在 defer 匿名函数里,且 defer 要在 panic 前注册
常见错误是把
放在普通代码块、
分支或
后面,这些位置根本不会执行,或执行时 panic 已结束。
❌ 错误:
——
永远执行不到
❌ 错误:
——
在 panic 之后注册,已失效
✅ 正确:
——
先注册,
在其内部直接调用
recover 无法捕获子 goroutine 的 panic
每个 goroutine 有独立的 panic/recover 作用域。主线程写了
+
,对
完全无效 —— 子 goroutine 会静默崩溃,主 goroutine 继续运行,你收不到任何通知。
HTTP worker 池中,每个 worker 必须自带
,不能指望中间件统一兜底
封装
启动协程时,
内部仍需自己加
,否则没用
没有“全局 recover”机制,跨 goroutine 捕获是语言层面不支持的
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 写入 —— 这些破坏不可逆
不要在
分支里调用 DB 写入、HTTP 请求、或依赖局部变量的函数
合理做法:记录 panic 栈和 request ID → 返回 500 或 fallback 响应 → 显式
或清理后退出当前任务
最易被忽略的一点:recover 不是 error 替代品,也不是事务回滚工具;它只提供一次“软着陆”机会,用错比不用更危险。
recover()ifpanic()func f() { panic("x"); r := recover() }recover()func f() { panic("x"); defer func() { r := recover() }() }deferfunc f() { defer func() { if r := recover(); r != nil { log.Print(r) } }(); panic("x") }deferrecover()deferrecovergo func() { panic("x") }()defer func() { recover() }()safeGo(f)fdeferrecover()recoverreturn