Go 语言入门笔记(八):错误处理与 panic/recover——Go 的“异常”哲学
前面写并发的时候几乎每个函数都返回了error然后就是if err ! nil那套。这篇就把 Go 的错误处理单独拎出来说透顺便聊聊 panic 和 recover。Go 没有 Java 那套 try-catch 异常机制一开始我很不习惯但写多了反而觉得这种显式的错误处理更清晰也更容易让人思考“这个错误到底该不该在这里处理”。Go 的 error 是什么Go 内置的error其实就是一个接口typeerrorinterface{Error()string}任何类型只要实现了Error() string方法就实现了error接口。所以自定义错误非常简单。errors.New 创建简单错误最常用的创建错误方式importerrorserr:errors.New(这是一个错误)fmt.Println(err.Error())// 这是一个错误fmt.Errorf 格式化错误err:fmt.Errorf(读取文件 %s 失败,test.txt)fmt.Println(err)// 读取文件 test.txt 失败fmt.Errorf内部其实就是调用errors.New只是多了格式化功能。错误处理的基本模式Go 里处理错误几乎是“约定俗成”的套路funcdoSomething()(int,error){// 业务逻辑return0,nil}result,err:doSomething()iferr!nil{// 处理错误log.Println(出错了:,err)return}// 正常流程fmt.Println(result)刚开始我觉得这种写法很啰嗦每个可能出错的函数都要跟着一个if err ! nil。但时间长了发现这种显式处理强迫你去思考每一个错误分支代码的健壮性反而更高。相比之下Java 的异常机制很容易让人忽略某些异常直到运行时才暴露。自定义错误类型有时候光靠errors.New不够需要携带更多上下文比如错误码、堆栈信息等。这时可以定义一个结构体来实现error接口typeMyErrorstruct{CodeintMessagestring}func(e*MyError)Error()string{returnfmt.Sprintf(code%d, message%s,e.Code,e.Message)}// 使用err:MyError{Code:404,Message:资源不存在}fmt.Println(err.Error())这种方式很灵活可以在错误里塞任何字段。很多第三方库都自定义了错误类型比如net.OpError、os.PathError等。错误包装%w 和 errors.Is / errors.As错误的包装Go 1.13 引入了错误包装机制用fmt.Errorf配合%w动词可以把一个错误包进另一个错误里funcreadFile(pathstring)error{_,err:os.Open(path)iferr!nil{returnfmt.Errorf(打开文件 %s 失败: %w,path,err)}returnnil}这样返回的错误包含了原始错误err同时增加了新的上下文信息。外层可以通过errors.Is或errors.As来检查是否包含某个特定错误。errors.Is判断错误链中是否包含某个错误err:readFile(test.txt)iferrors.Is(err,os.ErrNotExist){fmt.Println(文件不存在)}elseiferr!nil{fmt.Println(其他错误:,err)}errors.Is会沿着错误链一直找看是否包含目标错误。这样即便错误被包装了好几层也能准确判断出来。errors.As提取错误链中的特定类型varmyErr*MyErroriferrors.As(err,myErr){fmt.Println(错误码:,myErr.Code)}errors.As会检查错误链中是否存在某个具体类型的错误如果存在就赋值给目标变量。这在自定义错误类型时很有用。注意%w只能包装一个错误不能包装多个。而且最好只包装一次不要重复包装否则错误链会变得很啰嗦。panic 和 recover不是用来处理常规错误的Go 里还有一个panic机制可以让程序立即崩溃。但它不是用来处理普通错误的而是用来处理不可恢复的严重问题比如数组越界、空指针引用、除零等运行时错误。panic 的触发funcmain(){panic(程序崩溃了)fmt.Println(这行不会执行)}运行时会打印 panic 信息和堆栈然后退出。除了手动调用panic很多运行时错误也会触发 panic比如vars[]intfmt.Println(s[0])// panic: runtime error: index out of rangerecover 捕获 panicrecover是 Go 提供的唯一能从 panic 中恢复的机制。它必须在defer函数中调用才有效funcsafeRun(){deferfunc(){ifr:recover();r!nil{fmt.Println(捕获到 panic:,r)}}()panic(出事了)fmt.Println(这行不会执行)}funcmain(){safeRun()fmt.Println(程序继续执行)}输出捕获到 panic: 出事了 程序继续执行recover返回 panic 传入的值如果没有 panic 则返回nil。需要注意的是recover只能恢复同一个 goroutine 里的 panic跨 goroutine 的 panic 无法恢复。什么时候该用 panic原则能返回 error 就不要用 panic。panic 意味着程序进入不可控状态应该立即终止。一般用于程序启动时的致命错误如配置加载失败编程错误比如函数内部逻辑矛盾应该用 panic 暴露问题并发访问未初始化的 mapGo 运行时会 panic我刚开始写 Go 的时候总想用 panic 来简化错误处理结果被同事提醒panic 会中断整个程序而 error 让调用方有机会决定如何处理。所以现在除非真的无法继续运行否则一律返回 error。一个常见坑recover 只在 defer 函数里有效看这段代码funcwrongRecover(){ifr:recover();r!nil{fmt.Println(捕获到:,r)}panic(错误)}funcmain(){wrongRecover()fmt.Println(这行不会执行)}这段代码不会捕获 panic因为recover必须直接写在defer函数里而且要在 panic 发生之前已经注册。正确的做法是funccorrectRecover(){deferfunc(){ifr:recover();r!nil{fmt.Println(捕获到:,r)}}()panic(错误)}这个细节面试经常考。另一个坑panic 后 defer 的返回值如果函数有命名返回值在 panic 被 recover 后defer 可以修改返回值这也是前面讲 defer 时提到的。结合 panic/recover 可以写出比较高级的错误处理模式但用不好会让代码很费解建议少用。小结这篇把错误处理和 panic/recover 梳理了一遍error是接口任何实现Error() string的类型都可以当作错误。处理错误的基本模式返回error调用方if err ! nil检查。自定义错误类型可以携带更多信息。错误包装用%w配合errors.Is和errors.As判断错误链。panic用于不可恢复的错误recover只能在defer函数里有效。能返回 error 就不要用 panic这是 Go 的哲学。下一篇准备聊聊 Go 的包管理和依赖管理毕竟实际项目不可能只写一个文件。Go Modules 是怎么工作的怎么管理依赖版本还有工作区模式这些内容面试也经常问。到时候继续记录。如果这篇文章对你有帮助欢迎点赞收藏评论区一起交流。

相关新闻

Spring笔试错题集收录

Spring笔试错题集收录

2026/8/25 6:56:06 阅读更多 →
高级提示词技巧:角色、步骤、格式、约束

高级提示词技巧:角色、步骤、格式、约束

高级提示词技巧:角色、步骤、格式、约束📝 本章学习目标:通过本章学习,你将全面掌握"高级提示词技巧:角色、步骤、格式、约束"这一核心主题,建立系统性认知。一、引言:为什么这个话题…

2026/8/25 6:56:06 阅读更多 →
Unity C#进阶:抽象类Abstract Class的使用场景

Unity C#进阶:抽象类Abstract Class的使用场景

Unity C#进阶:抽象类Abstract Class的使用场景📚 本章学习目标:深入理解抽象类Abstract Class的使用场景的核心概念与实践方法,掌握关键技术要点,了解实际应用场景与最佳实践。本文属于《Unity工程师成长之路教程》Uni…

2026/8/25 6:56:06 阅读更多 →

最新新闻

近场DOA估计:降维MUSIC算法原理、实现与工程优化

近场DOA估计:降维MUSIC算法原理、实现与工程优化

1. 项目概述与核心价值上次我们聊了近场DOA估计的基本模型和传统MUSIC方法面临的“维度灾难”问题。很多朋友反馈说,原理懂了,但一看到那庞大的谱峰搜索计算量就头疼,感觉离实际应用还很远。这感觉我太懂了,当年我第一次把理论公式…

2026/8/25 8:08:35 阅读更多 →
C#启动外部进程与参数传递:ProcessStartInfo实战指南

C#启动外部进程与参数传递:ProcessStartInfo实战指南

1. 项目概述:从命令行到程序间通信的桥梁在C#开发中,尤其是开发桌面应用、工具软件或者系统集成项目时,一个非常高频且基础的需求就是:让我们的主程序去启动另一个独立的可执行文件(exe),并且还…

2026/8/25 8:08:35 阅读更多 →
C#启动外部EXE并传参:从ProcessStartInfo到进程交互的完整指南

C#启动外部EXE并传参:从ProcessStartInfo到进程交互的完整指南

1. 项目概述:从命令行到程序间通信在C#开发中,尤其是开发桌面应用、工具软件或者需要模块化协作的系统时,一个非常高频且基础的需求就是:让我的主程序去启动另一个独立的可执行文件(exe),并且不…

2026/8/25 8:08:35 阅读更多 →
hexo-theme-suka 社交分享与二维码导流:让博客跨设备传播的 3 个隐藏技巧

hexo-theme-suka 社交分享与二维码导流:让博客跨设备传播的 3 个隐藏技巧

hexo-theme-suka 社交分享与二维码导流:让博客跨设备传播的 3 个隐藏技巧 【免费下载链接】hexo-theme-suka 🎨Modern, powerful and simple theme for Hexo. 项目地址: https://gitcode.com/gh_mirrors/he/hexo-theme-suka hexo-theme-suka 是一…

2026/8/25 8:08:35 阅读更多 →
[特殊字符] AI 编程助手

[特殊字符] AI 编程助手

面向新手朋友的科普版 更新时间:2026年8月 目录 这两种工具是什么?开始前的准备工作(共通)Codex(OpenAI)安装教程Claude Code(Anthropic)安装教程第一次打开 & 登录常见问题 …

2026/8/25 8:08:35 阅读更多 →
手机实时提取SIM卡打电话的信令声音--社会价值(一、方案解决了什么问题)

手机实时提取SIM卡打电话的信令声音--社会价值(一、方案解决了什么问题)

手机实时提取SIM卡打电话的信令声音 --社会价值(一、方案解决了什么问题) 一、前言 蓝牙电话方案的初始目的,是为了解放双手,不用局限手机设备本身做接听操作。而是可以把手机当作一个移动的带SIM卡功能的模块,将呼叫和来电的能力转发给周…

2026/8/25 8:07:35 阅读更多 →

日新闻

洛谷 P7912:[CSP-J 2021 T4] 小熊的果篮 ← 双向链表

洛谷 P7912:[CSP-J 2021 T4] 小熊的果篮 ← 双向链表

【题目来源】 https://www.luogu.com.cn/problem/P7912 【题目描述】 小熊的水果店里摆放着一排 n 个水果。每个水果只可能是苹果或桔子,从左到右依次用正整数 1,2,…,n 编号。连续排在一起的同一种水果称为一个“块”。小熊要把这一排水果挑到若干个果篮里&#x…

2026/8/25 0:00:34 阅读更多 →
Transformers.js 网页端图像抠图实战:零后端 3 行代码返回透明 PNG

Transformers.js 网页端图像抠图实战:零后端 3 行代码返回透明 PNG

Transformers.js 网页端图像抠图实战:零后端 3 行代码返回透明 PNG 【免费下载链接】transformers.js State-of-the-art Machine Learning for the web. Run 🤗 Transformers directly in your browser, with no need for a server! 项目地址: https:/…

2026/8/25 0:00:34 阅读更多 →
数学建模竞赛论文写作指南:从模型构建到学术表达的核心技能

数学建模竞赛论文写作指南:从模型构建到学术表达的核心技能

1. 项目概述:从“会做”到“会写”的竞赛核心跃迁“全国大学生数学建模竞赛”,这个名字对理工科学生来说,分量极重。每年,无数团队在三天三夜的时间里,为一个开放性问题绞尽脑汁,从建立模型、求解算法到编程…

2026/8/25 0:00:34 阅读更多 →

周新闻

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

2026/8/25 3:38:12 阅读更多 →
SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

2026/8/25 3:38:18 阅读更多 →
Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/25 3:38:23 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/24 20:22:44 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/23 12:10:44 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/24 11:20:22 阅读更多 →