引言
在 Go 语言里,defer 关键字是大家很爱用的。因为他有着 defer+recover+panic 的组合拳打法,还有种各种 defer close 等常用场景。
defer 常见用法
在语法上,Go defer 的代码示例如下:
输出结果:
放学别走
煎鱼你好!
那 defer 在 Go 里的常见用法有哪些呢?首先是上文用到的,直接 defer + 函数:
其次是 defer+闭包的方式:
其他还有在面试题上常被考究的传参变形:
这些代码看起来,我们总是在对 defer 做闭包的各种声明和使用。defer 会不会就是和闭包天生一对?
新提案:defer 代码块
最近大家也在讨论一个与之相关的 Go 提案《proposal: Go 2: deferred code blocks》,由 @Damien Lloyd 提出,想看看有没有机会把 defer 的新语法落地。
原作者在使用 defer 时也是经常:
但这样就无法获得返回值。最终要变成:
基于上述类似的原因,想引入如下具有 defer 作用的代码块语法:
{...}
作者给出的代码示例:
defer {...}
反对的声音
当然,这看着似乎是比较美好的。看起来原提案作者只是简化了 defer 是的闭包使用,调整了作用域的范围。
但在社区内其实遭受比较多的反对声音。包含但不限于:
func()()
2、破坏兼容性:原 defer 关键字调用总是会跟着函数的词法调用,有良好的一致性。如果进行修改,会产生新的隐晦,破坏一致性。也会对现有的许多工具(例如:静态分析工具)产生影响,全要改。
defer func{}()defer {}
总结
if err != nil?
经过社区网友们指出后,发现这里猫腻不少。一门已经有 10+ 年的编程语言,还有 Go1 兼容性保障的。做出这类带作用域的提案变更,是有比较大的风险的。
同时对于 Go 工具链的影响,也是非常大的。一改,直接都完犊子了。确实需要尽量深思。原作者完全没提到。
该提案,正在开放 3 周等待意见收集。很神奇,没更多的人说话,但提案的表情给了很多个不认同。