Go 再讨论 catch error 模型,官方回应现状

大家好,我是煎鱼。

最近社区的同学和 Go 官方又因为错误处理的提案屡屡被否,发生了一些小的摩擦。也非常难得的看到核心团队成员首次表达了目前的态度和情况。

基于此,我们今天进行该内容分享。紧跟 Go 官方最新进展,看看官方对于错误处理的态度如何。

快速背景

Go 的错误处理机制,主要是依赖于 if err != nil 的方式。因此在对函数做一定的封装后。

代码会呈现出以下样子:

jy1, err := Foo1()
if err != nil {
    return err
}
jy2, err := Foo2()
if err != nil {
    return err
}
err := Foo3()
if err != nil {
    return err
}
...

有部分开发者会认为这比较的丑陋、混乱且难以阅读。

因此 Go 错误处理的优化,也是社区里一直反复提及和提出的领域。饱受各类争议。

新提案:追求类似 try-catch

最近一位国内的同学 @xiaokentrl 提了个类似 try catch error 的新提案,试图用魔法打败魔法。

aac3a35b61884091538c4ecd4c4aac8f.png

原作者给出的提案内容是:

1、新增环境变量做开关:

ERROR_SINGLE = TRUE   //error_single = true

2、使用特定标识符来做 try-catch:

Demo1 单行错误处理:

//Single-line error handling
file, err := os.Create("abc.txt") @ return nil , err
defer file.Close()

Demo2 多行错误处理:

func main() {
    //Multiline error handling
    :@

    file, err:= os.Open("abc.txt")
    defer file.Close()

    buf := make([]byte, 1024)
    _, err2 := file.Read(buf)

    @ err | err2  return ...
}

主要的变化内容是:利用标签 @ 添加一个类似 try-catch 的代码区块,并添加运算符和相关错误处理的联动规则。

这个提案本身,其实就是以往讲到的 goto error 和 check/with 这种类似 try-catch 的模式。

当然非常快的就遭到了 Go 核心团队的反对:

b86211072f7f2354bfcfa6b55227cac3.png

@Ian Lance Taylor 表示:由于很难处理声明和应用,如果一个标签的作用域中还有其他变量,就不能使用类似 goto 的用法。

新的争端:官方你行你上

社区中有同学看到这一次次被否的错误处理和关联提案们,深感无奈和无语。他发出了以下的质疑:

“为什么不让 Ian Lance Taylor 和/或 Go 核心团队的其他成员提出改进的错误处理框架的初始原型,然后让 Go 社区参与进来,为其最终形式做出贡献呢?Go 中的泛型正是这样发展到现在的。

如果我们等待 Go 社区提出最初的原型,我认为我们将永远不会有改进的 Go 错误处理框架,至少在未来几年内不会。”

但其实很可惜,因为人家真干过。

Go 核心团队是有主动提出过错误处理的优化提案的,提案名为《Proposal: A built-in Go error check function, try[1]》,快速讲一下。

以前的代码:

f, err := os.Open(filename)
if err != nil {
 return …, err  // zero values for other results, if any
}

应用该提案后的新代码:

f := try(os.Open(filename))

try 只能在本身会返回错误 error 结果的函数中使用,且该 error 结果必须是外层函数的最后一个结果参数。

不过很遗憾,该官方提案,喜提有史以来被否决最多的提案 TOP1:

9a9cbb2c43d01951a15ff9d60cf56d86.png

最终该提案也由于形形色色的意见,最终凉了。感觉也给 Go 核心团队泼了一盆凉水,因为这是继 check/handle 后的 try,到目前也没有新的官方提案了。

Go 官方回应

本次提及的新提案下,大家的交流愈演愈烈,有种认为就是 Go 核心团队故意不让错误处理得到更好的改善。

此时 Go 核心团队的元老之一 @Ian Lance Taylor 站出来发声,诠释了目前 Go 团队对此的态度。这也是首次。

具体内容如下:

6b1da4c3430ff0be8c5a428ee6e6c51c.png

“我们愿意考虑一个有良好社区支持的好的错误处理提案。

不幸的是,我很遗憾地说,基本上所有新的错误处理提案都不好,也没有社区支持。例如,这个提案有 10 个反对票,没有赞成票。我当然会鼓励人们在广泛使用这门语言之前,避免提交错误处理提案。

我还鼓励人们审查早期的提案。它们在这里:https://github.com/golang/go/issues?q=label%3Aerror-handling+ 。目前已有 183 个并在不断增加。

我自己阅读了每一个。重要的是,请记住,对已被否决提案的微调的新提案也几乎肯定也会被否决。

并且请记住,我们只会接受一个与现有语言契合良好的提案。例如:这个提案中使用了一个神奇的 @ 符号,这完全不像现有语言中的任何其他东西。

Go 团队可能会在适当的时候提出一个新的错误处理提案。然而,正如其他人所说,我们最好的想法被社区认为是不可接受的。而且有大量的 Go 程序员对现状表示满意。”

总结

目前 Go 错误处理的情况和困境是比较明确的,很多社区同学会基于以往已经被否决的旧提案上进行不断的微改,再不断提交。

现阶段都是被全面否定的,因为即使做了微调,也无法改变提案本身的核心思想。

而 Go 官方自己提出的 check/handle 和 try 提案,在社区中也被广大的网友否决了。还获得了史上最多人否决的提案的位置。

现阶段来看,未来 1-3 年内在错误处理的优化上仍然会继续僵持。

推荐阅读

参考资料

[1]

Proposal: A built-in Go error check function, try: https://github.com/golang/go/issues/67859

关注和加煎鱼微信,

一手消息和知识,拉你进技术交流群👇

3ce0470ff5b882bcd76068ce4f4eaeb1.jpeg

a96d9c62fc44d5daf49e193bc76129cc.png

你好,我是煎鱼,出版过 Go 畅销书《Go 语言编程之旅》,再到获得 GOP(Go 领域最有观点专家)荣誉,点击蓝字查看我的出书之路

日常分享高质量文章,输出 Go 面试、工作经验、架构设计,加微信拉读者交流群,和大家交流!

原创不易 点赞支持

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值