Golang使用errors.Is判断错误的正确方式
发布时间 - 2026-01-12 00:00:00 点击率:次errors.Is常返回false,因其仅检查错误链中是否存在同一底层错误值或指针,不支持字符串匹配;须用%w包裹、预定义变量或自定义Unwrap方法才能正确识别。
errors.Is 为什么经常返回 false?
因为 errors.Is 只检查错误链中是否存在某个**底层错误值(valu
e)或其指针**,不支持字符串匹配、模糊比较或自定义逻辑。如果你用 errors.New("timeout") 创建的错误和另一个同内容的 errors.New("timeout") 比较,errors.Is 一定返回 false —— 它们是两个不同地址的指针。
必须用 errors.New 或 fmt.Errorf 包装原始错误才能用 errors.Is
只有当错误被显式地用 fmt.Errorf("...: %w", err) 或 errors.Join 等方式包裹(即包含 %w 动词),它才进入错误链;否则 errors.Is 查不到。
- ✅ 正确:用
%w包裹底层错误 - ❌ 错误:只用
%s或拼接字符串,如fmt.Errorf("failed: %s", err.Error()) - ⚠️ 注意:
errors.Unwrap只能解一层,而errors.Is会自动遍历整个链(包括嵌套的%w)
err := io.EOF
wrapped := fmt.Errorf("read failed: %w", err)
fmt.Println(errors.Is(wrapped, io.EOF)) // true
自定义错误类型要实现 Unwrap 方法
如果自己定义了错误结构体(比如 type MyError struct{ Msg string; Code int }),默认 errors.Is 查不到它是否等于某个值,除非你显式实现 Unwrap() error 并返回底层错误。
- 若该错误本身是终端错误(无底层),
Unwrap应返回nil - 若它封装了另一个错误(如调用了
io.ReadFull),就返回那个错误 - 不要在
Unwrap中返回新构造的errors.New—— 地址不同,errors.Is仍失败
type MyError struct {
Err error
}
func (e *MyError) Error() string { return "my error" }
func (e *MyError) Unwrap() error { return e.Err } // ✅ 这样 errors.Is 才能穿透
判断标准错误时,优先用预定义变量而非 errors.New
Go 标准库导出的错误(如 io.EOF、os.ErrNotExist)是包级变量,地址唯一。直接拿它们做 errors.Is(err, io.EOF) 是安全且推荐的;但千万别写成 errors.Is(err, errors.New("EOF"))。
立即学习“go语言免费学习笔记(深入)”;
- ✅
errors.Is(err, io.EOF) - ✅
errors.Is(err, os.ErrNotExist) - ❌
errors.Is(err, errors.New("file does not exist")) - ⚠️ 第三方库若没暴露错误变量,应查文档看它是否实现了
Unwrap或提供了IsXXX()辅助函数
%w,导致上游再也无法用 errors.Is 判断原始错误类型。这个断点一旦出现,调试时就会发现“明明报了 EOF,却进不了 EOF 分支”。
# go
# golang
# app
# ai
# 标准库
# 为什么
# EOF
# String
# 封装
# Error
# 字符串
# 结构体
# int
# 指针
# Struct
# nil
# 自定义
# 不支持
# 的是
# 链中
# 中间层
# 遍历
# 它是
# 用了
# 时就
# 千万别
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
清除minerd进程的简单方法
Laravel如何配置.env文件管理环境变量_Laravel环境变量使用与安全管理
专业型网站制作公司有哪些,我设计专业的,谁给推荐几个设计师兼职类的网站?
Python自动化办公教程_ExcelWordPDF批量处理案例
Laravel路由Route怎么设置_Laravel基础路由定义与参数传递规则【详解】
网页设计与网站制作内容,怎样注册网站?
油猴 教程,油猴搜脚本为什么会网页无法显示?
Laravel Session怎么存储_Laravel Session驱动配置详解
Laravel如何实现RSS订阅源功能_Laravel动态生成网站XML格式订阅内容【教程】
如何在浏览器中启用Flash_2025年继续使用Flash Player的方法【过时】
Laravel队列由Redis驱动怎么配置_Laravel Redis队列使用教程
Android自定义listview布局实现上拉加载下拉刷新功能
Swift中循环语句中的转移语句 break 和 continue
标题:Vue + Vuex 项目中正确使用 JWT 进行身份认证的实践指南
Win11怎么查看显卡温度 Win11任务管理器查看GPU温度【技巧】
英语简历制作免费网站推荐,如何将简历翻译成英文?
Laravel如何编写单元测试和功能测试?(PHPUnit示例)
javascript如何操作浏览器历史记录_怎样实现无刷新导航
如何选择PHP开源工具快速搭建网站?
IOS倒计时设置UIButton标题title的抖动问题
如何在Windows服务器上快速搭建网站?
如何在Windows 2008云服务器安全搭建网站?
高端企业智能建站程序:SEO优化与响应式模板定制开发
Swift中switch语句区间和元组模式匹配
如何基于云服务器快速搭建个人网站?
Laravel用户密码怎么加密_Laravel Hash门面使用教程
Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)
如何在七牛云存储上搭建网站并设置自定义域名?
php485函数参数是什么意思_php485各参数详细说明【介绍】
如何用5美元大硬盘VPS安全高效搭建个人网站?
如何在Ubuntu系统下快速搭建WordPress个人网站?
Java Adapter 适配器模式(类适配器,对象适配器)优缺点对比
合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?
Android 常见的图片加载框架详细介绍
北京网站制作费用多少,建立一个公司网站的费用.有哪些部分,分别要多少钱?
如何自定义建站之星模板颜色并下载新样式?
HTML5打空格有哪些误区_新手常犯的空格使用错误【技巧】
Claude怎样写结构化提示词_Claude结构化提示词写法【教程】
如何实现建站之星域名转发设置?
Android滚轮选择时间控件使用详解
PHP怎么接收前端传的文件路径_处理文件路径参数接收方法【汇总】
学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?
中国移动官方网站首页入口 中国移动官网网页登录
Laravel如何保护应用免受CSRF攻击?(原理和示例)
做企业网站制作流程,企业网站制作基本流程有哪些?
Laravel怎么做数据加密_Laravel内置Crypt门面的加密与解密功能
如何快速生成ASP一键建站模板并优化安全性?
海南网站制作公司有哪些,海口网是哪家的?
CSS3怎么给轮播图加过渡动画_transition加transform实现【技巧】
如何在景安云服务器上绑定域名并配置虚拟主机?

