当前位置: 首页 > news >正文

Go 语言中的 `recover()` 函数详解

recover() 是 Go 语言中用于处理 panic 的内置函数,它允许程序管理发生 panic 的 goroutine 的行为。下面我将详细解释它的工作原理和使用方法。

基本概念

1. 函数签名

func recover() any

2. 核心功能

recover() 可以:

  • 停止 panic 的传播
  • 返回传递给 panic() 的值
  • 恢复正常的程序执行

工作原理

1. 使用位置

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

defer func() {if r := recover(); r != nil {// 处理 panic}
}()

2. 返回值

  • 当 goroutine 正在 panic 且在 defer 函数中调用时:返回传递给 panic() 的值
  • 其他情况(包括 panic 参数为 nil 的情况,Go 1.21 之前):返回 nil

使用示例

基本用法

func mayPanic() {panic("something went wrong")
}func main() {defer func() {if r := recover(); r != nil {fmt.Println("Recovered from panic:", r)}}()mayPanic()fmt.Println("This will not be executed if panic occurs")
}

输出:Recovered from panic: something went wrong

实际应用场景

func safeDivide(a, b int) (result int, err error) {defer func() {if r := recover(); r != nil {err = fmt.Errorf("runtime error: %v", r)}}()return a / b, nil
}

重要特性

  1. 必须与 defer 配合使用:只有在 defer 函数中直接调用才有效
  2. 作用域限制:只能恢复同一个 goroutine 中的 panic
  3. Go 1.21 的变化
    • 之前版本:panic(nil)recover() 返回 nil
    • Go 1.21+:panic(nil) 会引发 runtime panic,recover() 返回 *runtime.PanicNilError

注意事项

  1. 不要滥用 recover:应该只用于处理真正的意外情况,而不是替代常规错误处理
  2. 资源清理:即使 panic 被 recover,defer 函数仍然会执行
  3. 跨 goroutine:无法恢复其他 goroutine 的 panic
  4. 性能影响:panic/recover 比常规错误处理机制性能差

与 panic 的关系

recover()panic() 是配套使用的:

func doSomething() {defer func() {if r := recover(); r != nil {fmt.Println("Recovered:", r)}}()if somethingWrong {panic("critical error")}
}

最佳实践

  1. 为关键代码段添加 recover
  2. 记录 recover 到的错误信息
  3. 尽量让程序在 recover 后能继续正常运行
  4. 避免在库函数中静默地 recover 而不返回错误

相关文章:

  • 医疗生态全域智能化:从技术革新到价值重塑的深度探析
  • 基于Spring Boot 3.0、ShardingSphere、PostgreSQL或达梦数据库的分库分表
  • Go语言之路————接口、泛型
  • 在Anolis OS 8上部署Elasticsearch 7.16.1与JDK 11的完整指南
  • 首页数据展示
  • keep-alive具体使用方法
  • C++多线程与锁机制
  • MySQL 在 CentOS 7 环境下的安装教程
  • 如何解决 Xcode 签名证书和 Provisioning Profile 过期问题
  • 【Linux网络】深入解析I/O多路转接 - Select
  • 基于STM32的DS18B20简易温控系统LCD1602显示仿真设计
  • 论文阅读:2024 arxiv FlipAttack: Jailbreak LLMs via Flipping
  • AI 的未来是开源?DeepSeek 正在书写新篇章!
  • AI+零售:智能推荐、无人店与供应链管理的未来
  • 超越单体:进入微服务世界与Spring Cloud概述
  • 如何知道Ubuntu的端口是否被占用,被那个进程占用?如何终止进程
  • 大数据学习(115)-hive与impala
  • Redis性能优化终极指南:从原理到实战的深度调优策略
  • 【LeetCode 热题 100】矩阵置零 / 螺旋矩阵 / 旋转图像 / 搜索二维矩阵 II
  • 代码颜色模式python
  • 中日友好医院通报“医师肖某被举报”:基本属实,开除党籍并解聘
  • 榆林市委常委王华胜已任榆林市政协党组书记
  • 三杀皇马剑指四冠,硬扛到底的巴萨,赢球又赢人
  • 旧衣服旧纸箱不舍得扔?可能是因为“囤物障碍”
  • “一对一讨论诸多事宜”,泽连斯基披露此次特泽会更多细节
  • 持续更新丨伊朗港口爆炸事件已致561人受伤