如何使用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; ?>
】
相关推荐
- 小程序里php怎么变mp4_小程序调用php生成m
- Win10电脑C盘红了怎么清理_Windows10
- php订单日志怎么记录发货_php记录订单发货操作
- Python函数缓存机制_lru_cache解析【
- Win11怎么设置开机问候语_自定义Win11锁屏
- c++ try_emplace用法_c++ map
- Mac版Final Cut Pro入门_Mac视频
- php485在macos下怎么配置_php485
- 如何在Golang中配置代码格式化工具_使用gof
- Win11怎样激活系统密钥_Win11系统密钥激活
- Windows怎样关闭锁屏广告_Windows关闭
- 如何在Golang中使用time处理时间_Gola
- Windows10任务栏图标变成白色文件_Win1
- Win11如何卸载OneDrive_Win11卸载
- php删除数据怎么加限制_带where条件删除避免
- c++中如何使用std::variant_c++1
- php订单日志怎么记录评价_php记录订单评价日志
- 如何在Golang中编写异步函数测试_Golang
- Win11怎么修复系统文件_使用sfc命令修复Wi
- 如何使用Golang捕获测试日志_Golang t
- Win11怎么关闭用户账户控制UAC_Window
- Win11怎么关闭开机声音_Win11系统启动提示
- Windows蓝屏BAD_POOL_HEADER故
- PHP cURL GET请求:正确设置请求头与身份
- Golang如何遍历目录文件_Golang fil
- 如何使用Golang benchmark测量函数延
- Python文件操作优化_大文件与流处理解析【教程
- MAC如何安装Git版本控制工具_MAC开发环境配
- 如何在 Go 中创建包含映射(map)的切片(sl
- Mac自带的词典App怎么用_Mac添加和使用多语
- Win11怎么关闭透明效果_Windows11辅助
- Win11怎么解压RAR文件 Win11自带解压功
- Win11怎么更改账户头像_Windows 11自
- Win11用户账户控制怎么关_Win11关闭UAC
- Python脚本参数接收_sys与argparse
- php怎么操作Redis_Redis扩展连接与基本
- C++中的Pimpl idiom是什么,有什么好处
- Windows如何拦截2345弹窗广告_Windo
- c++怎么用jemalloc c++替换默认内存分
- MAC的“接续互通”功能无法使用怎么办_MAC检查
- 如何在Golang中使用闭包_封装变量与函数作用域
- Windows任务计划服务异常原因_任务调度失败的
- Win11怎么开启空间音效_Windows11耳机
- LINUX怎么设置系统语言_LINUX修改中文环境
- c++怎么使用std::tuple存储多元组数据_
- Python邮件系统自动化教程_批量发送解析与模板
- 如何用正则与预处理高效拦截带干扰符的恶意域名
- Mac怎么安装软件_Mac安装dmg与pkg文件的
- VSC里PHP变量未定义报错怎么解决_错误抑制技巧
- Mac系统更新下载慢或失败怎么办_解决macOS升

QQ客服