如何在Golang中使用defer和recover_Golang异常处理与defer语法-Golang

defer 在函数返回前按后进先出顺序执行,参数在 defer 语句出现时求值;recover 必须在 defer 函数中直接调用且仅对同 goroutine 中未结束的 panic 有效。

defer 语句的执行时机和栈顺序

defer 不是“异常时才执行”,而是函数返回前(包括正常 return、panic 中断、甚至函数末尾隐式返回)按后进先出(LIFO)顺序执行。很多人误以为 defer 只用于清理资源,其实它更核心的作用是“确定性地绑定执行时机”。

  • 多个 defer 语句会压入栈,最后定义的最先执行,比如:defer fmt.Println("a") 和 defer fmt.Println("b") 会输出 b 再 a
  • defer 表达式中的参数在 defer 语句出现时就求值(不是执行时),所以 var i = 0; defer fmt.Println(i); i = 1 输出的是 0
  • 如果想捕获变量的“执行时值”,需用匿名函数包裹:defer func(v int) { fmt.Println(v) }(i)

recover 必须在 defer 函数中直接调用才有效

recover() 只有在 panic 正在发生、且当前 goroutine 的 defer 链正在执行时才有意义;一旦 panic 结束或离开 defer 函数体,recover() 就返回 nil,起不到作用。

  • 以下写法无效:defer recover() —— 因为 recover() 是函数调用,不是函数值,且参数求值发生在 defer 注册时,此时 panic 还没发生
  • 正确写法必须是:defer func() { if r := recover(); r != nil { /* 处理 */ } }()
  • recover 对应的 panic 必须发生在同一 goroutine;跨 goroutine 的 panic 无法被另一个 goroutine 的 defer/recover 捕获

defer + recover 不能捕获所有“错误”,只对 panic 有效

Golang 没有传统 try/catch 异常机制,error 值是普通返回值,必须显式检查;recover 完全不介入 error 流程。混淆这两者是常见误区。

  • panic("network timeout") 可被 recover 拦截;return errors.New("timeout") 则完全无关
  • 标准库中绝大多数函数(如 json.Unmarshal、os.Open)都返回 error,不是 panic,不该也不需要 recover
  • 滥用 recover 试图兜底 error,会导致逻辑混乱、错误被静默吞掉、堆栈丢失

实际场景中 defer/recover 的合理用法

真正适合 recover 的场景极少:通常是顶层 goroutine(如 HTTP handler、goroutine 入口)防止 panic 导致整个服务崩溃,并记录日志;其他地方应优先用 error 返回 + 显式判断。

夏夕资源网专注于CMS网站模板,主流语言整站网站源码下载,网站建设相关教程分享,好用的软件素材整合下载,提供一站式便捷自助服务。
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"zy.lucklyus.top",如遇到无法解压的请联系管理员!
夏夕资源网-网站模板_免费源码_资源素材 » 如何在Golang中使用defer和recover_Golang异常处理与defer语法-Golang
在线时间:12:00 - 22:00
关注微信公众号:微信公众号
站长邮箱:[email protected]
  • 运营天数: 1391+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 3998017+
  • 本周更新: 0+
  • 最后更新: 2026-03-16

本站指数

×
  • 运营天数: 1391+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 3998017+
  • 本周更新: 0+
  • 最后更新: 2026-03-16