Go defer 去掉闭包函数及用法分析
引言
在 Go 语言里,defer 关键字是大家很爱用的。因为他有着 defer+recover+panic 的组合拳打法,还有种各种 defer close 等常用场景。
defer 常见用法
在语法上,Go defer 的代码示例如下:
package main import "fmt" func main() { defer fmt.Println("煎鱼你好!") fmt.Println("放学别走") }
输出结果:
放学别走
煎鱼你好!
那 defer 在 Go 里的常见用法有哪些呢?首先是上文用到的,直接 defer + 函数:
defer f()
其次是 defer+闭包的方式:
defer func() { result := f() // do something with result }()
其他还有在面试题上常被考究的传参变形:
func f1() int { i := 1 defer func() { i++ }() ... } func f2() int { i := 1 defer func(i int) { i++ }(i) .... }
这些代码看起来,我们总是在对 defer 做闭包的各种声明和使用。defer 会不会就是和闭包天生一对?
新提案:defer 代码块
最近大家也在讨论一个与之相关的 Go 提案《proposal: Go 2: deferred code blocks》,由 @Damien Lloyd 提出,想看看有没有机会把 defer 的新语法落地。
原作者在使用 defer 时也是经常:
defer f()
但这样就无法获得返回值。最终要变成:
defer func() { result := f() // do something with result }()
基于上述类似的原因,想引入如下具有 defer 作用的代码块语法:
defer { // 在封闭函数的末尾执行此操作 }
在使用了 defer 关键字的函数最后执行这整个代码块 {...}
。代码块中的每一行将按顺序运行。
作者给出的代码示例:
func fn() { f, err := os.Create("eddycjy.txt") if err != nil { panic(err) } defer { err := f.Close() if err != nil { panic(err) } } }
在 fn 函数,声明了 defer {...}
,代码块内是对 f.Close 的兜底判断和异常抛出。在函数结束后执行这整个代码块。
反对的声音
当然,这看着似乎是比较美好的。看起来原提案作者只是简化了 defer 是的闭包使用,调整了作用域的范围。
但在社区内其实遭受比较多的反对声音。包含但不限于:
1、收益比不高:这个提案只是避免了 func()
和 ()
等闭包声明,但是却要增加新的 defer 语法(语言语法更改会带来高昂成本),这个变更的 ROI 不高。
2、破坏兼容性:原 defer 关键字调用总是会跟着函数的词法调用,有良好的一致性。如果进行修改,会产生新的隐晦,破坏一致性。也会对现有的许多工具(例如:静态分析工具)产生影响,全要改。
3、作用域问题:原本 defer func{}()
的代码块结构下,你的代码作用域都限于闭包函数下。而使用新的 defer {}
的结构,该返回和操作,是否应该会影响到外部函数的结果?(这是最有争议的一点,作者也比较前言不搭后语,没明确指明语法意思)
总结
一开始乍一眼一看,感觉只是把 defer 关键字语句简化一下,好像特别好,省了几个单词。就像 if err != nil
也会有提要用 Rust 的 ?
等用法来替代的。
经过社区网友们指出后,发现这里猫腻不少。一门已经有 10+ 年的编程语言,还有 Go1 兼容性保障的。做出这类带作用域的提案变更,是有比较大的风险的。
同时对于 Go 工具链的影响,也是非常大的。一改,直接都完犊子了。确实需要尽量深思。原作者完全没提到。
该提案,正在开放 3 周等待意见收集。很神奇,没更多的人说话,但提案的表情给了很多个不认同。
以上就是Go defer 去掉闭包函数及用法分析的详细内容,更多关于Go defer闭包函数的资料请关注脚本之家其它相关文章!
相关文章
GoLang的sync.WaitGroup与sync.Once简单使用讲解
sync.WaitGroup类型,它比通道更加适合实现这种一对多的goroutine协作流程。WaitGroup是开箱即用的,也是并发安全的。同时,与之前提到的同步工具一样,它一旦被真正的使用就不能被复制了2023-01-01Go语言k8s kubernetes使用leader election实现选举
这篇文章主要为大家介绍了Go语言 k8s kubernetes 使用leader election选举,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2022-10-10
最新评论