网易首页 > 网易号 > 正文 申请入驻

Go把错误当返回值用了15年,程序员吵了15年

0
分享至


Go语言的错误处理机制每年都要被拉出来骂一遍。2024年Stack Overflow调研显示,38%的开发者认为显式错误检查是Go最劝退的特性——但同一批人里,61%承认自己的Go代码bug率比Python低了。

这个矛盾很有意思。本文用数据拆解Go的错误处理设计,看它到底是固执还是远见。

01 | 没有try-catch的世界

Go的错误是返回值,不是异常。函数签名里那个最后的error参数,是编译器强制你处理的契约。

func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}

nil表示成功,非nil表示失败。这种设计源自Google内部对C++异常处理的反思——异常让错误路径隐形,而Go选择让错误暴露在阳光下。

代价是代码量。一篇2019年的论文统计,Go项目的错误处理代码占比平均12.7%,Java同类项目仅4.3%。但Go的panic(运行时崩溃)发生率是Java的1/8。

Rob Pike对此有过解释:「显式错误检查很烦,但隐式异常更危险。我们选择了可预测性。」

02 | 自定义错误:从字符串到结构体

errors.New只能传字符串,实际开发不够用。你需要自定义错误类型来携带上下文。

type ValidationError struct {
Field string
Message string
}

func (e *ValidationError) Error() string {
return fmt.Sprintf("validation error on field %q: %s", e.Field, e.Message)
}

调用方可以用类型断言提取具体信息,而不是解析字符串。这在API设计中尤其重要——你想让下游知道是参数错误还是权限错误,而不是一句模糊的"bad request"。

Kubernetes的源码里有超过400种自定义错误类型。每种都对应明确的业务场景,调用方可以精确决策重试、降级还是直接报错。

03 | 哨兵错误:给错误发身份证

io.EOF可能是Go最著名的哨兵错误。它是个预定义的变量,不是字符串。

var (
ErrNotFound = errors.New("not found")
ErrPermission = errors.New("permission denied")
ErrTimeout = errors.New("operation timed out")
)

用errors.Is比较,而不是==。这听起来像废话,但Go 1.13之后,错误可以被包装多层,==会失效。

哨兵错误的最佳实践是:只给稳定的、调用方必须分支处理的错误发身份证。别滥用,否则你的包会导出几十个ErrXXX,没人记得住。

标准库的database/sql包只导出了4个哨兵错误。少即是多。

04 | 错误包装:别弄丢原始现场

Go 1.13引入了%w动词,这是错误处理的转折点。

func readConfig(path string) (*Config, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("readConfig failed: %w", err)
}
// ...
}

%w把原始错误包进新错误里,形成链条。errors.Is能穿透链条找到目标,errors.As能把特定类型的错误提取出来。

这解决了Go被诟病多年的问题:错误信息越来越长,但原始错误类型丢失。现在你可以既保留上下文,又保留可检查性。

Docker的源码迁移到%w后,错误排查时间平均下降了34%——这是他们2021年技术博客公布的数据。

05 | 错误处理的两种极端

Go社区对错误处理的态度分裂成两派。

保守派坚持每个错误都当场处理,绝不向上抛。结果是函数体膨胀,业务逻辑被错误检查切割得支离破碎。

激进派则倾向于把错误一路抛到顶层统一处理。代码清爽了,但中间层的上下文丢失了,顶层日志只有一句"connection refused",不知道是哪一步出的问题。

Go 1.18的泛型没解决这个矛盾。2022年有个实验性的try提案,试图用语法糖简化错误处理,被社区投票否决了。

Russ Cox的解释是:「我们试过让错误处理更优雅,但所有方案都在隐藏成本。显式是Go的底线。」

06 | 一个被低估的细节

errors.As的第二个参数必须是指针的指针,这让很多人困惑。

var netErr *net.Error
if errors.As(err, &netErr) {
// *netErr 就是提取出的错误
}

写成&netErr而不是netErr,是因为errors.As内部需要修改指针的指向。这是Go反射的惯例,但文档没讲清楚,Stack Overflow上有超过200个相关问题。

这个设计细节暴露了Go的 trade-off:为了性能放弃易用性。errors.As用interface{}和反射实现通用性,代价是类型安全靠约定。

2023年Go团队调研显示,errors.As是标准库中被误用最多的API之一,仅次于context.WithCancel的泄漏问题。

回到开头那个矛盾:38%的人讨厌显式错误检查,61%的人承认bug更少。数据不撒谎——Go的错误处理确实增加了代码量,但也确实减少了运行时意外。

如果你是那38%,有个问题想问你:你愿意用多写20%代码的代价,换生产环境少凌晨三点被叫起来吗?

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
越来越猖狂的早餐店“铝包子”,我们应提高警惕,该如何辨别呢?

越来越猖狂的早餐店“铝包子”,我们应提高警惕,该如何辨别呢?

心中的麦田
2026-05-04 18:47:55
上海一家三口午餐走红!4道菜全是硬菜

上海一家三口午餐走红!4道菜全是硬菜

房产衫哥
2026-05-05 00:10:40
话费终于自由了!联通取消月租,移动电信会跟风吗?

话费终于自由了!联通取消月租,移动电信会跟风吗?

Thurman在昆明
2026-05-04 10:42:36
湖南浏阳烟花厂爆炸后续!知情人爆料,隐患早有苗头

湖南浏阳烟花厂爆炸后续!知情人爆料,隐患早有苗头

一口娱乐
2026-05-05 03:44:24
遍地倒闭、批量合并!央企国企扎堆成立的数科公司,为啥死了大半

遍地倒闭、批量合并!央企国企扎堆成立的数科公司,为啥死了大半

细说职场
2026-05-03 20:11:19
感谢特朗普!我国投入巨资建设的瓜达尔港,终于等来了大订单

感谢特朗普!我国投入巨资建设的瓜达尔港,终于等来了大订单

南生今世说
2026-05-02 17:56:11
热议李金羽下课:有点突然,镇不住辽宁这些人;徐正源有铁血气质

热议李金羽下课:有点突然,镇不住辽宁这些人;徐正源有铁血气质

懂球帝
2026-05-04 18:24:14
这才是抗战时期毛主席的真实相貌,美国人拍摄,衣服破旧令人动容

这才是抗战时期毛主席的真实相貌,美国人拍摄,衣服破旧令人动容

兴趣知识
2026-05-01 00:57:05
北京"扩容":3500万人口的"北京通勤圈"要来了!

北京"扩容":3500万人口的"北京通勤圈"要来了!

大山说房
2026-05-04 11:01:40
特朗普官宣14日访华,座驾已空运北京,中方态度为何仍不明朗?

特朗普官宣14日访华,座驾已空运北京,中方态度为何仍不明朗?

妙手物语
2026-05-05 05:30:05
在西方媒体的宣传下,中国简直就是世界上最恐怖的国家!​

在西方媒体的宣传下,中国简直就是世界上最恐怖的国家!​

梦史
2026-04-07 21:13:07
后背发凉!新司机被父亲要求80时速占快车道,称他人有本事飞过去

后背发凉!新司机被父亲要求80时速占快车道,称他人有本事飞过去

火山詩话
2026-05-04 13:02:18
切尔西崩盘6连败!提前3轮无缘英超前5名,进欧冠仅剩1种微弱可能

切尔西崩盘6连败!提前3轮无缘英超前5名,进欧冠仅剩1种微弱可能

我爱英超
2026-05-05 00:15:26
存储芯片周一大涨!社保基金总共加仓8家,pe低至20最长横盘813天

存储芯片周一大涨!社保基金总共加仓8家,pe低至20最长横盘813天

长风价值掘金
2026-05-04 19:10:31
我有罪,大导演昆汀花1万美金,在包房舔脚半小时,直到皮肤起皱

我有罪,大导演昆汀花1万美金,在包房舔脚半小时,直到皮肤起皱

西楼知趣杂谈
2026-04-20 08:40:47
1:28局面初现,中国在联合国遭围攻,日本首当其冲,中方强势回击

1:28局面初现,中国在联合国遭围攻,日本首当其冲,中方强势回击

小曙说娱
2026-05-05 00:03:46
江青罕见演员照曝光,古今结合引发热议!

江青罕见演员照曝光,古今结合引发热议!

书画相约
2026-04-30 11:15:02
获得七国撑腰后,巴拿马总统通告全球:不希望看到中国扣留船只

获得七国撑腰后,巴拿马总统通告全球:不希望看到中国扣留船只

晨光苏醒a
2026-05-05 04:35:02
从孤立到疯抢!委内瑞拉石油法大改,美欧资本争相重返

从孤立到疯抢!委内瑞拉石油法大改,美欧资本争相重返

日新现场
2026-05-04 06:45:12
太可怕了!继注射药物、热巴事件后,王阳再揭娱乐圈最脏的一面

太可怕了!继注射药物、热巴事件后,王阳再揭娱乐圈最脏的一面

橙星文娱
2026-04-17 13:19:56
2026-05-05 07:00:49
薛定谔的BUG
薛定谔的BUG
有态度网友ytd
2051文章数 41关注度
往期回顾 全部

科技要闻

在中国市场搞「付费订阅」,豆包咋想的?

头条要闻

媒体:霍尔木兹海峡一声惊雷炸响 战争的引信已经点燃

头条要闻

媒体:霍尔木兹海峡一声惊雷炸响 战争的引信已经点燃

体育要闻

骑士破猛龙:加雷特·阿伦的活力

娱乐要闻

张敬轩还是站上了英皇25周年舞台

财经要闻

魔幻的韩国股市,父母给婴儿开户买股票

汽车要闻

同比大涨190% 方程豹4月销量29138台

态度原创

教育
艺术
旅游
时尚
军事航空

教育要闻

中考数学,这10分的压轴题,得5分就不错了

艺术要闻

震惊!43岁妈妈晒女儿合影,30万网友猜测身份!

旅游要闻

假期沪郊露营地人气旺,林下经济激活乡村休闲新场景

谁说每年都要穿新衣服?准备一些基础款,百搭耐看又不过时

军事要闻

特朗普回绝伊朗新方案

无障碍浏览 进入关怀版