panic 会终止当前函数并按 lifo 执行已注册 defer;recover 仅在 defer 中有效,可捕获本 goroutine 当前 panic,否则 panic 向上蔓延或导致程序退出。

panic 会立即终止当前函数,但 defer 仍照常执行
触发 panic 后,函数不会“跳过”已注册的 defer,而是进入「退出阶段」:所有已注册的 defer 按 LIFO(后进先出)顺序执行,哪怕 panic 发生在 defer 注册之后、函数返回之前。
- 若
defer中调用recover(),且该defer属于 panic 发生的同一函数或其上游调用链,则能捕获并停止传播 - 若
defer本身 panic(比如在 recover 之后又 panic 了),会覆盖当前 panic,原 panic 被丢弃 - 函数内未被 recover 的 panic 会向上一层调用者传播,同时触发上层函数的 defer 执行(只要它已注册)
panic 只影响当前 goroutine,不会跨协程传播
panic 是 goroutine 级别的机制。主 goroutine panic 会导致整个程序退出;其他 goroutine panic 若未 recover,则仅该 goroutine 终止,其余 goroutine 继续运行——但这容易引发资源泄漏或状态不一致。
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
- HTTP 服务中每个请求通常跑在独立 goroutine,必须在 handler 入口加
defer+recover(),否则一个请求 panic 会 kill 掉整个服务进程 -
recover()在非 defer 函数里调用永远返回nil,因为它只对“当前 goroutine 正在展开的 panic”有效 - 不能用
recover()捕获其他 goroutine 的 panic,也没有跨 goroutine 的 panic 传递机制
recover 必须紧贴 defer,且只能捕获本 goroutine 最近一次未恢复的 panic
recover() 不是“全局监听器”,它只在 defer 函数体内有效,且只对当前 goroutine 当前正在展开的那个 panic 生效。一旦该 panic 被 recover,它就从调用栈中移除,后续再调用 recover() 将返回 nil。
- 多个 defer 嵌套时,只有最内层那个成功调用
recover()的 defer 能拿到 panic 值;外层 defer 再调用recover()返回nil - 如果 panic 被 recover 后,代码继续执行并再次 panic,这属于“新 panic”,与之前无关,需另配 defer/recover 捕获
-
recover()返回的是panic()传入的任意值(interface{}类型),不是error,需类型断言才能安全使用
panic 传播终止于 main 函数末尾或未被捕获的调用栈顶
当 panic 一路向上未被任何 recover() 拦截,最终到达 main 函数末尾时,Go 运行时打印堆栈并以状态码 2 退出。此时所有 defer(包括 main 里的)都已执行完毕,但程序不再继续。
- 错误信息里第一行(如
panic: runtime error: index out of range)是 panic 根因,往下才是调用栈;应优先看最深层那一行的文件和行号 - 若在
init()中 panic,程序甚至无法进入main(),直接崩溃,且不会执行任何main中的 defer - 使用
runtime/debug.PrintStack()或debug.Stack()可在 recover 里手动记录完整堆栈,比默认输出更可控
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










