3.7 Go panic 与 recover 学习笔记
1. panic — 触发程序崩溃panic立即中断当前函数的执行开始逐层退出unwind如果没有被 recover 捕获整个程序崩溃package mainimportfmtfuncdemonstratePanic(){fmt.Println(Before panic)panic(Something went wrong!)fmt.Println(After panic)// 这行永远不会执行}funcmain(){fmt.Println( demonstratePanic with recovery )func(){deferfunc(){ifr :recover();r!nil{fmt.Println(Caught panic from demonstratePanic:, r)}}()demonstratePanic()}()}执行结果demonstratePanic with recoveryBefore panic Caught panic from demonstratePanic: Something went wrong!要点panic(Something went wrong!)立即中断函数“After panic” 不会执行panic 会触发函数逐层退出unwind每一层的 defer 都会执行如果没有任何 recover 捕获程序崩溃并打印 panic 信息和堆栈追踪本例用匿名函数 defer/recover 包裹了 demonstratePanic所以 panic 被捕获程序继续运行panic 的适用场景不可恢复的错误如配置缺失、逻辑矛盾不要用于普通错误处理2. defer recover 捕获 panicrecover()只能在 defer 函数内调用用于捕获 panic 并恢复程序执行package mainimportfmtfunc safeDivide(a, b int)(result int){deferfunc(){ifr :recover();r!nil{fmt.Println(Recovered from panic:, r)result0// 设置 panic 情况下的返回值}}()ifb0{panic(division by zero)}returna / b}funcmain(){// 正常情况 fmt.Println( safeDivide normal case )result1 :safeDivide(10,2)fmt.Println(Result:, result1)// panic 情况 fmt.Println(\n safeDivide panic case )result2 :safeDivide(10,0)fmt.Println(Result:, result2)}执行结果safeDivide normalcaseResult:5safeDivide paniccaseRecovered from panic: division by zero Result:0要点recover()返回 panic 传入的值此处是字符串 “division by zero”如果没有 panic 则返回nilrecover只能在 defer 函数内调用直接调用 recover不在 defer 中永远返回 nilresult 0利用命名返回值result在 defer 中修改 panic 情况下的返回值正常情况recover()返回 nil不进入 if 分支result保持a/b 5panic 情况recover()返回 “division by zero”进入 if 分支result被设为 03. recover 捕获运行时 panic越界访问等recover 可以捕获 Go 运行时产生的 panic如数组越界、nil 指针等package mainimportfmtfunc processArray(arr[]int){deferfunc(){ifr :recover();r!nil{fmt.Println(Recovered from array access panic)}}()value :arr[10]// 如果 arr 长度11运行时 panic fmt.Println(Value at index 10:, value)}funcmain(){// 短数组越界 panic fmt.Println( processArray with short array )shortArr :[]int{1,2,3}processArray(shortArr)// 长数组正常访问 fmt.Println(\n processArray with long array )longArr :make([]int,15)fori :0;i15;i{longArr[i]i *10}processArray(longArr)}执行结果processArray with short arrayRecovered from array access panicprocessArray with long arrayValue at index10:100要点shortArr只有 3 个元素访问arr[10]导致运行时 panicindex out of rangelongArr有 15 个元素arr[10] 10010*10100正常输出recover 不区分 panic 来源无论是手动panic()还是运行时错误都能捕获常见的运行时 panic数组越界、nil 指针访问、类型断言失败、除零等4. 嵌套 panic 与 recover — 只有最内层的 recover 能捕获panic 只会被最近的最内层的recover 捕获外层的 recover 收到 nilpackage mainimportfmtfuncnestedPanic(){deferfunc(){fmt.Println(Outer recovery:, recover())// 这里会是 nil}()func(){deferfunc(){fmt.Println(Inner recovery:, recover())// 这里捕获 panic}()panic(Inner panic)}()}funcmain(){fmt.Println( nestedPanic example )nestedPanic()}执行结果nestedPanic exampleInner recovery: Inner panic Outer recovery:nil要点内层匿名函数的 recover 捕获了 “Inner panic”panic 在这里被恢复外层 nestedPanic 的 recover 收到nil因为 panic 已经被内层处理了原理panic 沿调用栈逐层 unwind遇到第一个 recover 就被捕获并停止 unwind这意味着一旦 panic 被 recover更高层的函数感知不到有 panic 发生过类似 try-catch内层 catch 捕获异常后外层 catch 不会再收到该异常5. recover 后程序继续运行panic 被 recover 捕获后程序从 recover 所在的 defer 函数返回处继续正常执行package mainimportfmtfunc safeDivide(a, b int)(result int){deferfunc(){ifr :recover();r!nil{fmt.Println(Recovered from panic:, r)result0}}()ifb0{panic(division by zero)}returna / b}func processArray(arr[]int){deferfunc(){ifr :recover();r!nil{fmt.Println(Recovered from array access panic)}}()value :arr[10]fmt.Println(Value at index 10:, value)}funcdemonstratePanic(){fmt.Println(Before panic)panic(Something went wrong!)fmt.Println(After panic)}funcnestedPanic(){deferfunc(){fmt.Println(Outer recovery:, recover())}()func(){deferfunc(){fmt.Println(Inner recovery:, recover())}()panic(Inner panic)}()}funcmain(){result1 :safeDivide(10,2)fmt.Println(Result:, result1)result2 :safeDivide(10,0)fmt.Println(Result:, result2)shortArr :[]int{1,2,3}processArray(shortArr)longArr :make([]int,15)fori :0;i15;i{longArr[i]i *10}processArray(longArr)func(){deferfunc(){ifr :recover();r!nil{fmt.Println(Caught panic from demonstratePanic:, r)}}()demonstratePanic()}()nestedPanic()// 所有 panic 都被 recover程序继续正常运行 fmt.Println(\nProgram continues normally)}执行结果Result:5Recovered from panic: division by zero Result:0Recovered from array access panic Value at index10:100Before panic Caught panic from demonstratePanic: Something went wrong!Inner recovery: Inner panic Outer recovery:nilProgram continues normally要点所有的 panic 都被 recover 捕获程序没有崩溃最后输出 “Program continues normally”证明 recover 后程序继续正常运行panic/recover 不是普通的错误处理机制Go 推荐用error处理可预期的错误panic/recover 适用于真正不可恢复的场景、库的内部防护、顶层兜底恢复知识点总结知识点关键概念panic 触发panic(msg)立即中断函数panic 后的代码不执行defer recoverrecover 只能在 defer 内调用捕获 panic 值并恢复执行recover 修改返回值利用命名返回值在 defer 中设置 panic 情况的返回值捕获运行时 panic数组越界、nil 指针等运行时错误也能被 recover 捕获嵌套 panic/recoverpanic 只被最内层 recover 捕获外层 recover 返回 nilrecover 后继续运行panic 被 recover 后程序从恢复点继续正常执行最佳实践可预期错误用error不可恢复错误用 panic/recover 兜底

相关新闻

10GW算力集群核心技术解析:从异构计算到分布式训练实战

10GW算力集群核心技术解析:从异构计算到分布式训练实战

最近在技术圈里,SpaceXAI 这个名字被频繁提及,尤其是在其宣布“目标明年实现 10GW 算力集群”之后。对于开发者而言,这不仅仅是一条商业新闻,更是一个强烈的技术信号:大规模、高密度的算力集群正在从云端走向更广泛的产…

2026/10/13 1:06:46 阅读更多 →
T3 Code V2 + Claude:AI代理GUI部署与核心功能实测指南

T3 Code V2 + Claude:AI代理GUI部署与核心功能实测指南

这类工具最值得先看的不是功能列表,而是能不能在普通环境里稳定跑起来,以及它到底解决了什么具体问题。T3 Code V2 结合 Claude 的这套方案,核心是提供了一个图形化的 AI 代理操作界面,让你能在一个统一的窗口里,更直观…

2026/10/13 1:50:49 阅读更多 →
从零到一发布npm包:实战指南与避坑手册

从零到一发布npm包:实战指南与避坑手册

1. 从想法到发布:一个npm包的完整旅程最近在整理自己的工具库,发现有几个常用的函数在好几个项目里都复制粘贴了无数遍。每次修个bug或者加个新特性,都得在所有项目里手动同步一遍,效率低不说,还容易出错。相信很多前端…

2026/10/13 1:57:47 阅读更多 →

最新新闻

Java 设计模式之 Template View:用模板视图分离静态布局与动态内容,打造可复用网页渲染骨架

Java 设计模式之 Template View:用模板视图分离静态布局与动态内容,打造可复用网页渲染骨架

示例工程教程 【免费下载链接】java-design-patterns Design patterns implemented in Java 项目地址: https://gitcode.com/GitHub_Trending/ja/java-design-patterns 点击查看 免费下载 导读:Template View(模板视图)是一种面向…

2026/10/14 2:05:18 阅读更多 →
电力弹簧技术在主动配电网中的关键应用与优化

电力弹簧技术在主动配电网中的关键应用与优化

1. 电力弹簧技术背景与配电网痛点电力弹簧(Electric Spring)作为第三代柔性电力电子装置,本质上是一种具备快速响应能力的电压/电流双模式补偿器。与传统STATCOM、SVG等无功补偿设备相比,其独特之处在于能够通过智能控制算法主动调…

2026/10/14 2:05:18 阅读更多 →
OpenClaw 会话工具(Session Tools)完全指南:sessions_list / sessions_history / sessions_send / sessions_spawn

OpenClaw 会话工具(Session Tools)完全指南:sessions_list / sessions_history / sessions_send / sessions_spawn

人工智能大模型LLM 网关AI Agent即时通讯 【免费下载链接】openclaw-zero-token OpenClaw: Use All Major AI Models NO API Token! Claude/ChatGPT/Gemini/DeepSeek/Doubao/Grok/Qwen/Manus/Kimi 项目地址: https://gitcode.com/gh_mirrors/op/openclaw-zero-token…

2026/10/14 2:05:18 阅读更多 →
T3 Stack实战:t3code如何实现端到端类型安全的全栈开发

T3 Stack实战:t3code如何实现端到端类型安全的全栈开发

t3code 这个名字,乍一看确实有点抽象。但如果你这几年一直混在 Next.js 和 TypeScript 的圈子里,看到 t3 前缀,大概率会想到那个火得一塌糊涂的 T3 Stack——Next.js、TypeScript、tRPC、Prisma、Tailwind 再加上 NextAuth 的组合。t3code 其…

2026/10/14 2:05:18 阅读更多 →
仓颉框架 CJoy 配置模块测试设计:从 config-tests 规格到测试用例实现

仓颉框架 CJoy 配置模块测试设计:从 config-tests 规格到测试用例实现

后端Web框架MCP 服务 【免费下载链接】cjoy 一个高性能、可扩展、轻量、省心的仓颉应用开发框架。IoC,Rest,宏路由,Json,中间件,参数绑定与校验,文件上传下载,OAuth2,MCP...... 项目…

2026/10/14 2:05:18 阅读更多 →
voidImageViewer 项目内 WebP 规范文档生成指南:用 kramdown 从 Markdown 文本源构建 Container Spec HTML

voidImageViewer 项目内 WebP 规范文档生成指南:用 kramdown 从 Markdown 文本源构建 Container Spec HTML

桌面应用图像处理 【免费下载链接】voidImageViewer Lightweight image viewer for Windows with animated GIF/WEBP support 项目地址: https://gitcode.com/gh_mirrors/vo/voidImageViewer 点击查看 免费下载 本篇技术指南讲解 voidImageViewer 仓库所集成的 lib…

2026/10/14 2:04:18 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/12 18:11:17 阅读更多 →