注册

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 的新提案,试图用魔法打败魔法。



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


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 核心团队的反对:



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


新的争端:官方你行你上


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


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


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


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


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


以前的代码:


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

应用该提案后的新代码:


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

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


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



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


Go 官方回应


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


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


具体内容如下:



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


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


我还鼓励人们审查早期的提案。它们在这里:github.com/golang/go/i… 。目前已有 183 个并在不断增加。


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


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


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


总结


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


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


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


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



作者:煎鱼eddycjy
来源:juejin.cn/post/7381741857708752905

0 个评论

要回复文章请先登录注册