如何使用Golang recover捕获panic_防止程序崩溃并处理异常
技术百科
P粉602998670
发布时间:2026-01-01
浏览: 次 Go语言用panic/recover+defer实现异常处理,recover仅在defer函数中有效且限于当前goroutine;需在易错逻辑外层封装safeRun等模式,子goroutine须独立加recover;recover后不继续执行panic点,仅恢复调度并返回。
Go语言中没有传统意义上的try-catch机制,而是通过panic和recover配合defer来实现运行时异常的捕获与恢复。关键在于:recover只能在defer函数中调用才有效,且仅能捕获当前goroutine中的panic。
recover必须配合defer使用
recover不是全局拦截器,它只在defer延迟执行的函数中调用时
才起作用。如果写在普通逻辑里,返回值始终为nil,无法捕获任何panic。
- 正确写法:在可能panic的函数内,先用
defer注册一个匿名或命名函数,在其中调用recover() - 错误写法:把
recover()放在if判断里、或者放在panic之后但不在defer中
典型安全封装模式
常见做法是将易出错逻辑包裹进一个带recover的闭包,统一处理异常:
func safeRun(f func()) {
defer func() {
if r := recover(); r != nil {
log.Printf("panic recovered: %v", r)
// 可记录日志、上报监控、返回默认值等
}
}()
f()
}
调用方式:safeRun(func() { riskyOperation() })。这样即使riskyOperation触发panic,程序也不会退出,而是继续执行后续逻辑。
注意goroutine隔离性
每个goroutine有独立的panic/recover作用域。主goroutine中defer的recover无法捕获子goroutine里的panic。
- 子goroutine需自行加defer+recover,例如启动时就包装:
go func() { defer safeRecover(); doWork() }() - HTTP服务中,标准
http.ServeMux已内置recover(如net/http包),但自定义handler仍建议手动加一层防护
recover后不能“继续执行”panic发生点
recover的作用是让程序从panic状态恢复正常调度,但它不会回到panic发生的那行代码继续执行。控制权会回到defer所在函数的末尾,然后按正常流程返回。
- 例如:函数A中defer了recover,A内部某处panic → 执行defer函数 → recover成功 → A函数直接返回,不执行panic之后的代码
- 因此,recover适合做“兜底清理”和“错误转化”,不适合用来“重试”或“修正错误后续跑完”
# go语言
# go
# golang
# if
# red
# 封装
# 作用域
# try
# catch
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Win11怎么设置虚拟内存_Windows 11优
- Win11怎么设置虚拟内存最佳大小_Windows
- 如何在Mac上搭建Golang开发环境_使用Hom
- Win11如何设置鼠标灵敏度_Win11鼠标灵敏度
- Win11时间格式怎么改成12小时制 Win11时
- php做exe支持多线程吗_并发处理实现方式【详解
- Windows怎样拦截QQ浏览器广告_Window
- 如何开启Windows的远程服务器管理工具(RSA
- c++ stringstream用法详解_c++字
- Win11怎么更改系统语言_Win11中文语言包下
- MAC如何修改默认应用程序_MAC文件后缀关联设置
- MAC如何设置网卡MAC地址克隆_MAC终端修改物
- 手机php文件怎么变成mp4_安卓苹果打开php转
- Python对象比较与排序_魔术方法解析【教程】
- 如何在Golang中实现微服务服务拆分_Golan
- 如何在Windows中创建新的用户账户?(标准与管
- Win11开机Logo怎么换_Win11自定义启动
- 手机php怎么转mp4_手机端php文件转mp4a
- Win11时间不对怎么同步_Win11自动校准互联
- 如何在 Go 同包不同文件中正确引用结构体
- 如何用::实现工具类方法调用_php静态工具类设计
- php订单日志怎么导出excel_php导出订单日
- Python大型项目拆分策略_模块化解析【教程】
- Golang如何测试HTTP中间件_Golang
- Python对象比较与排序_集合使用说明【指导】
- Windows10如何删除恢复分区_Win10 D
- Linux如何申请SSL免费证书_Linux下Ce
- 如何使用Golang处理网络超时错误_Golang
- Go 中的 := 运算符:类型推导机制与使用边界详
- Win11如何更改用户账户文件夹名称 Win11修
- Windows系统时间服务错误_W32Time服务
- Python大文件处理策略_内存优化说明【指导】
- Go语言中正确反序列化多个同级XML元素为结构体切
- 如何解决同一段404代码在不同主机上表现不一致的问
- php8.4如何配置ssl证书_php8.4htt
- mac怎么右键_MAC鼠标右键设置与触控板手势技巧
- php高频调试功能有哪些_php常用调试函数与工具
- Windows10怎么备份注册表_Windows1
- Windows 11怎么设置默认解压软件_Wind
- php删除数据怎么清空表_truncate与del
- Python多线程使用规范_线程安全解析【教程】
- C++中的协变与逆变是什么?C++函数指针与返回类
- windows如何禁用驱动程序强制签名_windo
- Win10如何卸载WindowsDefender_
- 为什么Go需要go mod文件_Go go mod
- 如何诊断并终止卡死的 multiprocessin
- Windows蓝屏错误0x00000023怎么修复
- PHP的FastAdmin架构适合二次开发吗_特点
- Win11搜索不到蓝牙耳机怎么办 Win11蓝牙驱
- 如何在Golang中定义接口_抽象方法和多态实现

QQ客服