<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 2901字,需瀏覽 6分鐘

           ·

          2023-07-19 17:37

          大家好,我是煎魚。

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

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

          defer 常見用法

          在語法上,Go defer 的代碼示例如下:

                package?main

          import?"fmt"

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

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

          輸出結(jié)果:

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

          那 defer 在 Go 里的常見用法有哪些呢?首先是上文用到的,直接 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)
          ?....
          }

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

          新提案:defer 代碼塊

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

          4eb7ac035efcae353edfb01fcbdaa081.webp

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

                defer?f()

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

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

          基于上述類似的原因,想引入如下具有 defer 作用的代碼塊語法:

                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)然,這看著似乎是比較美好的。看起來原提案作者只是簡(jiǎn)化了 defer 是的閉包使用,調(diào)整了作用域的范圍。

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

          1、收益比不高:這個(gè)提案只是避免了 func()() 等閉包聲明,但是卻要增加新的 defer 語法(語言語法更改會(huì)帶來高昂成本),這個(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、作用域問題:原本 defer func{}() 的代碼塊結(jié)構(gòu)下,你的代碼作用域都限于閉包函數(shù)下。而使用新的 defer {} 的結(jié)構(gòu),該返回和操作,是否會(huì)影響到外部函數(shù)的結(jié)果?(這是最有爭(zhēng)議的一點(diǎn),作者也比較前言不搭后語,沒明確指明語法意思)

          總結(jié)

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

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

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

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

          1803ba14b86e86b5d246417d86a3f25a.webp

          推薦閱讀


          參考資料 [1]

          proposal: Go 2: deferred code blocks: https://github.com/golang/go/issues/38520


          關(guān)注和加煎魚微信,

          一手消息和知識(shí),拉你進(jìn)技術(shù)交流群??


          7ff34319198c744481e957e5694aff6c.webp


          你好,我是煎魚,出版過 Go 暢銷書《Go 語言編程之旅》,再到獲得 GOP(Go 領(lǐng)域最有觀點(diǎn)專家)榮譽(yù),點(diǎn)擊藍(lán)字查看我的出書之路

          日常分享高質(zhì)量文章,輸出 Go 面試、工作經(jīng)驗(yàn)、架構(gòu)設(shè)計(jì),加微信拉讀者交流群,和大家交流!

          瀏覽 33
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美国产精品一二三产品在哪买 | 中文字幕成人在线视频 | 天天看 天天干 | 亚洲日韩视频 | 高清无码视频免费观看 |