大家好,我是煎鱼。
对于 Go 这一门编程语言,Go 核心团队的成员自己心里也非常有数,持续最久的吐槽就是错误处理的冗长。
当然,从我们的角度来看,社区还存在对于 Go 错误处理现有机制不满意的情况。
近期 Go 官方发表了《[ On | No ] syntactic support for error handling[1]》正式宣布对错误处理机制的想法和后续表态。今天分享给大家。
Go1 错误处理的 “冗长” 例子
Go 的 if err != nil
的最短例子如下:
x, err := call()
if err != nil {
// handle err
}
更常见的代码例子如下:
func printSum(a, b string) error {
x, err := strconv.Atoi(a)
if err != nil {
return err
}
y, err := strconv.Atoi(b)
if err != nil {
return err
}
fmt.Println("result:", x + y)
return nil
}
这个函数大概只有 10 余行,但是实际上只有 3-4 行在实际上做逻辑调用和处理,剩余的 6 行都在处理 err
变量的冗余。
这样的冗长,就是为什么有关错误处理的吐槽排在每年的 Go 开发者调查报告前列的缘由。

这样一看,其实就是 Go1 自带的错误处理方式和机制,就是会被一部份同学疯狂吐槽的(也有支持的)

非常见仁见智了。
Go 核心团队的多轮尝试
Go 核心团队疯狂表示多人在多年做过多轮的积极尝试。
最早可以追溯到 2018 年,时任团队负责人的 @Russ Cox 想将该问题的优化放进 Go2 的大篮子里一起解决了。
团队中的 @Marcel van Lohuizen 提出了《Error Handling — Draft Design[2]》的提案,示例代码如下:
// printSum implementation using the proposed check/handle mechanism.
func printSum(a, b string) error {
handle err { return err }
x := check strconv.Atoi(a)
y := check strconv.Atoi(b)
fmt.Println("result:", x + y)
return nil
}
但,这被认为太复杂。又没有办法继续推进。僵持住了。
随后在 2019 年,根据新的 try 提案《Proposal: A built-in Go error check function, try[3]》又做了改善。
示例代码如下:
// printSum implementation using the proposed try mechanism.
func printSum(a, b string) error {
// use a defer statement to augment errors before returning
x := try(strconv.Atoi(a))
y := try(strconv.Atoi(b))
fmt.Println("result:", x + y)
return nil
}
但是由于在出现错误时,可能会出现在深度嵌套诱发 try,以及 try 会打乱控制流的问题。导致许多人我无法接受 try 提案。并成功被称为:“臭名昭著”。最终被迫放弃。
又经过多年的折腾,@Ian Lance Taylor 参考 Rust 发布了新的提案《proposal: spec: reduce error handling boilerplate using ?[4]》。
示例代码如下:
// printSum implementation using the proposed "?" statements.
func printSum(a, b string) error {
x := strconv.Atoi(a) ?
y := strconv.Atoi(b) ?
fmt.Println("result:", x + y)
return nil
}
实际上 @Ian Lance Taylor 还做了小型的用户实操实验,当时绝大部分参与者都能够意识到 ?
的作用是什么。他才敢放心(有信心)继续推进。
但是依然很不幸,这个提案依然被很多的建议和想法给淹没。没法得出一个最终的最优解。
由此,Go 核心团队的 10+ 年对于错误处理机制探讨的推进。被迫暂告一段落。甚至引发了 Go 团队很多的 “反思”。
最终结论(阶段性)
Go 核心团队认为,其在过去那么多年,一共提出了 3 个成熟的提案和数百个社区提案。但是这些所有的提案,都未能够得到足够的社区支持。
最终(2025 年)Go 官方将决定停止尝试解决错误处理机制的问题。给出的理由是提案流程里的:

“提案流程的目标是及时就结果达成普遍共识。如果提案审查无法在问题跟踪器上的问题讨论中达成普遍共识,通常的结果就是拒绝提案。”
同时有两个非常扎心的事实:
截止至目前,没有任何一个错误处理提案达成共识。全部无一例外都被拒绝了。
Google Go 团队的资深成员们,也没有达成最佳的前进共识。(没有强而有力的共识)
说白了。就是搞不定。没有最佳的错误处理方式。且消耗了太大的精力和时间,官方团队自己也没有达成共识。

在 2025 年 6 月做出了最终的决定:“在可预见的将来,Go 语言团队将停止针对错误处理的语法修改。我们还将关闭所有主要涉及错误处理语法的开放式提案和新提案,不再进行进一步调查。”
总结
实际上 Go 这一门编程语言的 Go 错误处理机制,一直处于用户调查中的风头浪尖。但是会在互联网上发声的仅仅是一部分人。
但在现实和其他没发声的人里,也有很多支持 Go 不需要改变语法,直接还是用现在的 if err != nil
。也是存在非常多的支持者。(这一点官方在 Google Cloud Next 2025 做了个小型聚会进行了相关讨论)
从现实来讲,Go 核心团队感觉非常想找到一个完美的错误处理机制,但现阶段来看,正因为想一碗水都端平。似乎都无法解决。可能还是需要当年 rsc 力推 go module 时的决心。
但很可惜,现在和社区最为亲近的 ian 也已经离职了,一时半会肯定不会有所改善的了。
参考资料
[1]
[ On | No ] syntactic support for error handling: https://go.dev/blog/error-syntax
[2]Error Handling — Draft Design: https://go.googlesource.com/proposal/+/master/design/go2draft-error-handling.md
[3]Proposal: A built-in Go error check function, try: https://go.googlesource.com/proposal/+/master/design/32437-try-builtin.md
[4]proposal: spec: reduce error handling boilerplate using ?: https://github.com/golang/go/issues/71203
关注和加煎鱼微信,
一手消息和知识,拉你进技术交流群👇
你好,我是煎鱼,出版过 Go 畅销书《Go 语言编程之旅》,再到获得 GOP(Go 领域最有观点专家)荣誉,点击蓝字查看我的出书之路。
日常分享高质量文章,输出 Go 面试、工作经验、架构设计,加微信拉读者交流群,和大家交流!
原创不易 点赞支持