目录
什么时候该用 recover?
怎么正确使用 recover 恢复?
recover 的局限性和注意事项
写 recover 的常见模式
首页 后端开发 Golang 如何从恐慌中恢复过来?

如何从恐慌中恢复过来?

Jul 23, 2025 am 04:11 AM
go panic恢复

Panic 在 Go 中如同程序“心脏病发作”,recover 可作为“急救工具”防止崩溃,但 recover 仅在 defer 函数中生效。1. recover 用于避免服务挂掉、记录日志、返回友好错误。2. 必须配合 defer 使用,仅对同 goroutine 生效,恢复后程序不回到 panic 点。3. 建议在顶层或关键入口使用,不滥用,优先使用 error 处理。4. 常见模式是封装 safeRun 函数包裹可能 panic 的逻辑。掌握其使用场景与限制,才能正确发挥其作用。

How to recover from a panic in Go?

Panic 在 Go 里就像程序突然“心脏病发作”,如果不及时处理,整个流程就可能直接终止。但好在 Go 提供了 recover 这个“急救工具”,可以让你在 panic 发生后尽量稳住程序,不让它崩溃。

How to recover from a panic in Go?

不过要注意的是,recover 只能在 defer 调用的函数中生效,不是什么地方都能随便一抓就恢复的。


什么时候该用 recover?

panic 不是错误处理的首选方式,但在某些严重出错、无法继续执行的情况下会触发。这时候你可能想:

How to recover from a panic in Go?
  • 避免整个服务挂掉(比如 web server 处理请求时)
  • 抓住异常并记录日志,方便排查问题
  • 返回一个友好的错误信息而不是直接崩溃

这个时候,recover 就派上用场了。特别是在中间件或者全局拦截器中,recover 常用于捕获意外 panic 并做兜底处理。


怎么正确使用 recover 恢复?

recover 的使用有固定套路,基本结构如下:

How to recover from a panic in Go?
defer func() {
    if r := recover(); r != nil {
        fmt.Println("Recovered in f", r)
    }
}()

几个关键点要记住:

  • 必须配合 defer 使用:recover 必须放在 defer 函数中才有效。
  • 只能在同一个 goroutine 中恢复:如果你在一个 goroutine 里 panic,另一个 recover 是抓不到的。
  • recover 后程序不会回到 panic 点:程序从 defer 函数返回后继续执行后续逻辑,panic 点之后的代码不会再运行。

举个实际例子:你在处理 HTTP 请求时不小心访问了一个空指针,如果没 recover,整个服务可能崩掉;用了 recover,至少可以把这个请求标记为失败,不影响其他请求。


recover 的局限性和注意事项

虽然 recover 能救命,但它不是万能的,有些情况它也无能为力:

  • 不能跨 goroutine 恢复:如果你在子 goroutine 里 panic,主函数的 recover 是看不到的。
  • recover 后堆栈已经破坏:虽然程序不崩了,但状态可能已经不一致,需要谨慎处理后续逻辑。
  • 不该滥用 recover:它更像是最后防线,不应该用来代替正常的错误检查。

所以建议:

  • 尽量只在顶层或关键入口处使用 recover(比如 main 函数、HTTP handler)
  • recover 后最好记录详细信息,便于定位问题
  • 对于已知可能出错的地方,优先用 error 返回而不是依赖 panic/recover

写 recover 的常见模式

很多项目都会封装一个通用的 recover 函数,比如这样:

func safeRun(fn func()) {
    defer func() {
        if r := recover(); r != nil {
            log.Printf("Recovered: %v", r)
        }
    }()
    fn()
}

然后这样调用:

safeRun(func() {
    // 可能 panic 的代码
})

这种写法在并发任务或定时任务中很实用,可以避免某个任务崩溃导致整体失败。


基本上就这些。recover 不复杂,但容易用错。掌握它的使用场景和限制,才能真正让它发挥价值。

以上是如何从恐慌中恢复过来?的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

PHP教程
1517
276
登录的一些最佳实践是什么? 登录的一些最佳实践是什么? Aug 04, 2025 pm 04:48 PM

使用结构化日志记录、添加上下文、控制日志级别、避免记录敏感数据、使用一致的字段名、正确记录错误、考虑性能、集中监控日志并统一初始化配置,是Go中实现高效日志的最佳实践。首先,采用JSON格式的结构化日志(如使用uber-go/zap或rs/zerolog)便于机器解析和集成ELK、Datadog等工具;其次,通过请求ID、用户ID等上下文信息增强日志可追踪性,可通过context.Context或HTTP中间件注入;第三,合理使用Debug、Info、Warn、Error等级别,并通过环境变量动

如何优雅地关闭Go服务? 如何优雅地关闭Go服务? Aug 05, 2025 pm 08:21 PM

usesignal.notify()

如何在Go中获得当前时间 如何在Go中获得当前时间 Aug 06, 2025 am 11:28 AM

usetime.now()togetThecurrentLocalTimeasatime.timeObject; 2. formattheTime usedtheformatMethodWithLayoutSlike“ 2006-01-0215:04:05”; 3.getutctimebybbybbycallingcallingutc {

您如何配置GO代码以进行性能? 您如何配置GO代码以进行性能? Aug 05, 2025 am 08:50 AM

Go代码性能分析可通过内置pprof工具实现,首先导入\_"net/http/pprof"启用调试端点;1.对HTTP服务,在程序中启动localhost:6060的pprof接口;2.使用gotoolpprofhttp://localhost:6060/debug/pprof/profile?seconds=30收集30秒CPU性能数据;3.通过gotoolpprofhttp://localhost:6060/debug/pprof/heap分析内存分配情况;4.启用run

如何在GO中解析XML数据 如何在GO中解析XML数据 Aug 05, 2025 pm 07:24 PM

解析XML数据在Go中非常简单,只需使用内置的encoding/xml包即可。1.定义带有xml标签的结构体来映射XML元素和属性,如xml:"name"对应子元素,xml:"contact>email"处理嵌套,xml:"id,attr"读取属性;2.使用xml.Unmarshal将XML字符串解析为结构体;3.对于文件,使用os.Open打开后通过xml.NewDecoder解码,适合大文件流式处理;4.处理重复元素时,在结构

如何在GO应用程序中执行登录? 如何在GO应用程序中执行登录? Aug 04, 2025 pm 03:48 PM

使用标准库log包适合简单场景,但缺乏日志级别和结构化支持;2.Go1.21 推荐使用内置的slog,支持结构化日志和多种处理器,适合大多数现代应用;3.高性能生产环境首选zap,具备极快的处理速度和丰富的功能;4.避免在新项目中使用已不再活跃维护的logrus;应根据Go版本、性能需求和是否需要结构化日志来选择合适的库,优先考虑slog或zap。

使用GO和云功能构建无服务器API 使用GO和云功能构建无服务器API Aug 05, 2025 pm 01:21 PM

要构建一个无服务器API,需先设置Go环境并安装GoogleCloudSDK,然后编写一个HTTP函数处理请求,最后通过gcloudCLI部署到CloudFunctions。1.安装Go1.18 和GoogleCloudSDK并配置项目;2.创建Go模块并编写HTTP处理函数,支持GET和POST方法,处理JSON输入并返回响应;3.简化代码仅保留Handler函数,移除本地服务器逻辑;4.使用gcloud命令部署函数,指定运行时、入口点和触发方式;5.测试API的GET和POST接口,验证返回

您如何交叉编译GO应用程序? 您如何交叉编译GO应用程序? Aug 06, 2025 am 05:52 AM

跨跨卷务式的buirt-insupportviagoosandgoarch.1.setgoosforthetargetoperatingsystem(例如Linux,linux,windows,darwin).2.setgoarchforthetArgetArgatArchArchitArchTarchitContractractection(E.G.,AMD64,AMD64,AMD64,AMD64,AMD64,AMD64,ARM64)

See all articles