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 年内在错误处理的优化上仍然会继续僵持。
文章持续更新,可以微信搜【脑子进煎鱼了】阅读,本文 GitHub github.com/eddycjy/blo… 已收录,学习 Go 语言可以看 Go 学习地图和路线,欢迎 Star 催更。
推荐阅读
- Go1.0 到 1.22 的性能表现,提高了多少倍?
- Google 如果把 Go 团队给裁了会怎么样?
- Go 未来方向:标准库 v2 改进的指导原则
原文链接: https://juejin.cn/post/7381741857708752905
文章收集整理于网络,请勿商用,仅供个人学习使用,如有侵权,请联系作者删除,如若转载,请注明出处:http://www.cxyroad.com/17332.html