自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Go defer 去掉閉包函數(shù),靠譜嗎?

開(kāi)發(fā) 前端
一開(kāi)始乍一眼一看,感覺(jué)只是把 defer 關(guān)鍵字語(yǔ)句簡(jiǎn)化一下,好像特別好,省了幾個(gè)單詞。就像 if err != nil? 也會(huì)有提要用 Rust 的 ? 等用法來(lái)替代的。

大家好,我是煎魚(yú)。

在 Go 語(yǔ)言里,defer 關(guān)鍵字是大家很愛(ài)用的。因?yàn)樗兄?defer+recover+panic 的組合拳打法,還有種各種 defer close 等常用場(chǎng)景。

這是 Go 語(yǔ)言開(kāi)發(fā)者必知必會(huì)的編程姿勢(shì)。

defer 常見(jiàn)用法

在語(yǔ)法上,Go defer 的代碼示例如下:

package main

import "fmt"

func main() {
 defer fmt.Println("煎魚(yú)你好!")

 fmt.Println("放學(xué)別走")
}

輸出結(jié)果:

放學(xué)別走
煎魚(yú)你好!

那 defer 在 Go 里的常見(jiàn)用法有哪些呢?首先是上文用到的,直接 defer + 函數(shù):

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)
 ....
}

這些代碼看起來(lái),我們總是在對(duì) defer 做閉包的各種聲明和使用。defer 會(huì)不會(huì)就是和閉包天生一對(duì)?

新提案:defer 代碼塊

最近大家也在討論一個(gè)與之相關(guān)的 Go 提案《proposal: Go 2: deferred code blocks[1]》,由 @Damien Lloyd 提出,想看看有沒(méi)有機(jī)會(huì)把 defer 的新語(yǔ)法落地。

圖片圖片

原作者在使用 defer 時(shí)也是經(jīng)常:

defer f()

但這樣就無(wú)法獲得返回值。最終要變成:

defer func() { 
   result := f()
   // do something with result
}()

基于上述類(lèi)似的原因,想引入如下具有 defer 作用的代碼塊語(yǔ)法:

defer {
   // 在封閉函數(shù)的末尾執(zhí)行此操作
}

在使用了 defer 關(guān)鍵字的函數(shù)最后執(zhí)行這整個(gè)代碼塊 {...}。代碼塊中的每一行將按順序運(yùn)行。

作者給出的代碼示例:

func fn() {
    f, err := os.Create("eddycjy.txt")
    if err != nil {
        panic(err)
    }

    defer {
       err := f.Close()

       if err != nil {
          panic(err)
       }
    }
}

在 fn 函數(shù),聲明了 defer {...},代碼塊內(nèi)是對(duì) f.Close 的兜底判斷和異常拋出。在函數(shù)結(jié)束后執(zhí)行這整個(gè)代碼塊。

反對(duì)的聲音

當(dāng)然,這看著似乎是比較美好的??雌饋?lái)原提案作者只是簡(jiǎn)化了 defer 是的閉包使用,調(diào)整了作用域的范圍。

但在社區(qū)內(nèi)其實(shí)遭受比較多的反對(duì)聲音。包含但不限于以下幾點(diǎn):

1、收益比不高:這個(gè)提案只是避免了 func() 和 () 等閉包聲明,但是卻要增加新的 defer 語(yǔ)法(語(yǔ)言語(yǔ)法更改會(huì)帶來(lái)高昂成本),這個(gè)變更的 ROI 不高。

2、破壞兼容性:原 defer 關(guān)鍵字調(diào)用總是會(huì)跟著函數(shù)的詞法調(diào)用,有良好的一致性。如果進(jìn)行修改,會(huì)產(chǎn)生新的隱晦,破壞一致性。也會(huì)對(duì)現(xiàn)有的許多工具(例如:靜態(tài)分析工具)產(chǎn)生影響,全要改。

3、作用域問(wèn)題:原本 defer func{}() 的代碼塊結(jié)構(gòu)下,你的代碼作用域都限于閉包函數(shù)下。而使用新的 defer {} 的結(jié)構(gòu),該返回和操作,是否會(huì)影響到外部函數(shù)的結(jié)果?(這是最有爭(zhēng)議的一點(diǎn),作者也比較前言不搭后語(yǔ),沒(méi)明確指明語(yǔ)法意思)

總結(jié)

一開(kāi)始乍一眼一看,感覺(jué)只是把 defer 關(guān)鍵字語(yǔ)句簡(jiǎn)化一下,好像特別好,省了幾個(gè)單詞。就像 if err != nil 也會(huì)有提要用 Rust 的 ? 等用法來(lái)替代的。

經(jīng)過(guò)社區(qū)網(wǎng)友們指出后,發(fā)現(xiàn)這里貓膩不少。一門(mén)已經(jīng)有 10+ 年的編程語(yǔ)言,還有 Go1 兼容性保障的。做出這類(lèi)帶作用域的提案變更,是有比較大的風(fēng)險(xiǎn)的。

同時(shí)對(duì)于 Go 工具鏈的影響,也是非常大的。一改,直接都完?duì)僮恿?。確實(shí)需要盡量深思。原作者完全沒(méi)提到。

該提案,我寫(xiě)的時(shí)候正在開(kāi)放 3 周等待意見(jiàn)收集。很神奇,沒(méi)更多的人說(shuō)話(huà),但提案的表情給了很多個(gè)不認(rèn)同。

責(zé)任編輯:武曉燕 來(lái)源: 腦子進(jìn)煎魚(yú)了
相關(guān)推薦

2019-03-21 12:10:56

騰訊管理年輕化

2014-02-11 09:25:09

2022-10-24 08:55:13

Go工具鏈開(kāi)發(fā)者

2013-12-30 16:22:40

Windows 9概念設(shè)計(jì)

2015-07-31 10:16:17

2016-11-22 17:26:11

開(kāi)源PowerShellLinux

2021-01-12 14:24:26

Python開(kāi)發(fā)大數(shù)據(jù)

2020-10-14 15:15:28

JavaScript(

2021-01-22 07:48:07

JavaScript 高階函數(shù)閉包

2015-12-29 10:10:04

私有云虛擬化公共云

2013-07-19 10:29:54

大數(shù)據(jù)數(shù)據(jù)挖掘

2015-06-08 10:06:53

路由器

2015-06-17 14:44:36

大數(shù)據(jù)填高考志愿

2018-12-03 16:17:56

資管行業(yè)人工智能投資者

2021-04-01 14:35:08

XDR微步在線(xiàn)

2021-10-26 13:18:52

Go底層函數(shù)

2015-09-21 13:39:30

2014-12-30 10:20:24

飛機(jī)WiFi

2021-01-04 14:21:21

人工智能機(jī)器學(xué)習(xí)語(yǔ)言

2020-11-09 09:28:49

WiFi 7WIFI6網(wǎng)絡(luò)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)