【Go语言基础【14】】defer与异常处理(panic、recover)

发布时间:2026/11/3 1:24:48

【Go语言基础【14】】defer与异常处理(panic、recover) 文章目录零、概述一、defer关键字延迟执行机制1. 基本原理2. defer下变量的作用域3. 典型应用场景二、异常处理机制panic(类java throw)与recover(捕获)1. panic触发异常2. recover捕获异常三、defer与recover结合使用1. 通用异常处理模板2. 多层调用中的异常传递零、概述关键字/函数作用描述defer延迟执行函数用于资源释放、日志记录等按LIFO顺序执行panic触发异常终止当前协程正常执行可显式调用或由运行时错误触发recover在defer中捕获panic恢复程序执行避免崩溃执行顺序defer→return→panic若未捕获最佳实践defer用于资源管理panic/recover用于不可恢复的严重错误处理注意事项defer的性能影响每个defer会创建一个栈帧过多使用可能影响性能尤其在高频调用的函数中。建议仅在必要场景如资源释放中使用defer避免滥用。panic的合理使用不建议在业务逻辑中滥用panic应优先使用多返回值如(result, error)处理可预期的错误。推荐场景处理不可恢复的严重错误如配置文件缺失、数据库连接失败。recover的作用范围recover仅能捕获当前协程的panic无法跨协程捕获如其他goroutine中的panic。跨协程异常处理需通过通道channel传递错误。一、defer关键字延迟执行机制1. 基本原理核心特性独立的defer栈延迟执行defer修饰的函数或语句会在当前函数即将退出时执行包括正常返回、panic异常或提前return。栈存储多个defer按**后进先出LIFO**顺序执行先声明的后执行。值拷贝defer语句中的参数在声明时立即求值并拷贝后续修改不影响其值。defer的作用一般用来做善后操作例如清理垃圾、释放资源无论是否报错都执行defer对象。另一方面defer可以让这些善后操作的语句和开始语句放在一起无论在可读性上还是安全性上都很有改善毕竟写完开始语句就可以直接写defer语句永远也不会忘记关闭、善后等操作执行顺序示例funcdeferOrder(){fmt.Println(开始执行)deferfmt.Println( defer 1)// 压栈顺序1 → 2 → 3deferfmt.Println( defer 2)deferfmt.Println( defer 3)fmt.Println(执行结束)// 先于 defer 执行}// 输出// 开始执行// 执行结束// defer 3 最后压栈最先执行// defer 2// defer 12. defer下变量的作用域1值拷贝机制funcdeferValueCopy(){x:10deferfmt.Println(defer值拷贝,x)// 声明时拷贝x的值10x20// 修改不影响 defer 中的值fmt.Println(修改后x,x)// 输出20}// defer输出defer值拷贝102闭包引用funcdeferClosure(){x:10deferfunc(){// 闭包引用外部变量x非值拷贝fmt.Println(闭包引用,x)// 取函数退出时的x值}()x20fmt.Println(修改后x,x)// 输出20}// defer输出闭包引用20defer 延迟执行的是一个匿名函数闭包闭包不直接捕获值而是引用外部变量 x。3. 典型应用场景1资源释放文件、网络连接等funcreadFile(pathstring){file,err:os.Open(path)iferr!nil{panic(err)}deferfile.Close()// 确保文件最终关闭// 处理文件逻辑}2记录日志或统计耗时funcprocess(){start:time.Now()deferfunc(){// 函数结束时打印耗时fmt.Printf(处理耗时%v\n,time.Since(start))}()// 模拟业务逻辑time.Sleep(1*time.Second)}3错误处理中的资源回滚functransaction(){db,err:openDB()iferr!nil{panic(err)}deferdb.Rollback()// 事务失败时回滚需配合 recover// 执行数据库操作db.Commit()// 成功则提交}二、异常处理机制panic(类java throw)与recover(捕获)1. panic触发异常核心作用当程序遇到致命错误如空指针解引用、除数为零时panic会中断当前协程的正常执行并逐层向上抛出异常最终导致程序崩溃除非被recover捕获。触发时机显式调用主动调用panic(“错误信息”)触发异常如业务逻辑错误。隐式触发Go 运行时自动抛出如内存越界、类型断言失败。示例显式panicfuncdivide(a,bint)int{ifb0{panic(除数不能为零)// 触发异常}returna/b}funcmain(){divide(10,0)// 程序崩溃输出panic信息}**运行时panic示例**funcruntimePanic(){varptr*int// nil指针fmt.Println(*ptr)// 运行时panic: invalid memory address}2. recover捕获异常作用在defer函数中调用recover()捕获当前协程的panic并恢复执行。注意:仅在defer修饰的函数中有效其他位置调用返回nil。捕获后可继续执行defer函数但当前函数会立即退出后续代码不执行。正确用法funcsafeDivide(a,bint){deferfunc(){iferr:recover();err!nil{// 捕获panicfmt.Println(捕获异常,err)// 输出捕获异常除数不能为零}}()ifb0{panic(除数不能为零)// 触发异常被defer捕获}fmt.Println(a/b)}funcmain(){safeDivide(10,0)// 正常执行不崩溃}错误用法funcwrongRecover(){recover()// 非defer中调用无效panic(测试)// 未捕获程序崩溃}三、defer与recover结合使用1. 通用异常处理模板funcprotect(fnfunc()){// 保护任意函数防止panicdeferfunc(){iferr:recover();err!nil{fmt.Println(全局异常处理,err)}}()fn()// 执行可能panic的函数}funcmain(){protect(func(){panic(业务逻辑异常)// 被保护函数捕获})}2. 多层调用中的异常传递funclevel3(){panic(level3 panic)// 触发panic}funclevel2(){level3()// 传递panic}funclevel1(){deferfunc(){iferr:recover();err!nil{fmt.Println(在level1捕获,err)// 捕获level3的panic}}()level2()// 调用下层函数}funcmain(){level1()// 输出在level1捕获level3 panic}
延伸阅读

更多相关文章

2026/11/3 1:24:48

PP-OCRv5_server_det_onnx开发者指南:如何扩展和定制文字检测功能

PP-OCRv5_server_det_onnx开发者指南:如何扩展和定制文字检测功能 PP-OCRv5_server_det_onnx是飞桨PaddlePaddle推出的高效文字检测工具,基于ONNX格式模型,专为服务端部署优化。本文将详细介绍如何扩展和定制其文字检测功能,帮助…

2026/11/3 1:19:48

【线性代数】【第二章】矩阵习题

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 1:19:48

【线性代数】【第一章】行列式习题

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 2:24:51

folia-major 安装与首次跑通指南:30 分钟点亮全屏歌词动画

folia-major 安装与首次跑通指南:30 分钟点亮全屏歌词动画 【免费下载链接】folia-major 专注于绚丽的歌词动画效果的本地音乐/navidrome/第三方多平台在线音乐播放器 项目地址: https://gitcode.com/GitHub_Trending/fo/folia-major Folia(仓库名…

2026/11/3 2:24:51

5分钟装好网盘直链下载助手:8大网盘直链解析一步到位

5分钟装好网盘直链下载助手:8大网盘直链解析一步到位 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼云…

2026/11/3 2:19:51

理解 GC Roots:对象为什么不能被回收

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/2 6:08:01

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/2 6:39:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 1:04:48

STM32实战:基于MAX14431数字隔离器的SPI隔离通信方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 1:04:48

工业SPI隔离通信设计:MAX14431BAEE+与STM32L4A6RG实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 1:04:48

STM32+NRF24L01无线抢答器:硬件设计、通信协议与低功耗实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/2 6:08:01

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/2 6:39:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑