主頁 > 知識庫 > 淺談go中defer的一個隱藏功能

淺談go中defer的一個隱藏功能

熱門標(biāo)簽:西部云谷一期地圖標(biāo)注 地圖標(biāo)注的汽車標(biāo) 中國地圖標(biāo)注省會高清 浙江高速公路地圖標(biāo)注 學(xué)海導(dǎo)航地圖標(biāo)注 南通如皋申請開通400電話 廣州呼叫中心外呼系統(tǒng) 高德地圖標(biāo)注口訣 江西轉(zhuǎn)化率高的羿智云外呼系統(tǒng)

在開始使用Go進(jìn)行編碼時,Defer是要關(guān)注的一個很重要的特性。它非常簡單:在任何函數(shù)中,給其他函數(shù)的調(diào)用加上前綴 defer以確保該函數(shù)在外部函數(shù)退出之前立即執(zhí)行,即使外部函數(shù)出現(xiàn)異常被中斷,該延遲函數(shù)也將運行。

但是,你還可以使用defer在任何函數(shù)開始后和結(jié)束前執(zhí)行配對的代碼。這個隱藏的功能在網(wǎng)上的教程和書籍中很少提到。要使用此功能,需要創(chuàng)建一個函數(shù)并使它本身返回另一個函數(shù),返回的函數(shù)將作為真正的延遲函數(shù)。在 defer 語句調(diào)用父函數(shù)后在其上添加額外的括號來延遲執(zhí)行返回的子函數(shù)如下所示:

func main() {
  defer greet()() 
  fmt.Println("Some code here...")
}

func greet() func() {
  fmt.Println("Hello!")
  return func() { fmt.Println("Bye!") } // this will be deferred
}

輸出以下內(nèi)容:

Hello!
Some code here...
Bye!

父函數(shù)返回的函數(shù)將是實際的延遲函數(shù)。父函數(shù)中的其他代碼將在函數(shù)開始時(由 defer 語句放置的位置決定)立即執(zhí)行。

這為開發(fā)者提供了什么能力?因為在函數(shù)內(nèi)定義的匿名函數(shù)可以訪問完整的詞法環(huán)境(lexical environment),這意味著在函數(shù)中定義的內(nèi)部函數(shù)可以引用該函數(shù)的變量。在下一個示例中看到的,參數(shù)變量在measure函數(shù)第一次執(zhí)行和其延遲執(zhí)行的子函數(shù)內(nèi)都能訪問到:

func main() {
  example()
  otherExample()
}

func example(){
  defer measure("example")()
  fmt.Println("Some code here")
}

func otherExample(){
  defer measure("otherExample")()
  fmt.Println("Some other code here")
}

func measure(name string) func() {
  start := time.Now()
  fmt.Printf("Starting function %s\n", name)
  return func(){ fmt.Printf("Exiting function %s after %s\n", name, time.Since(start)) }
}

輸出以下內(nèi)容:

Starting example
Some code here
Exiting example after 0s
Starting otherExample
Some other code here
Exiting otherExample after 0s

此外函數(shù)命名的返回值也是函數(shù)內(nèi)的局部變量,所以上面例子中的measure函數(shù)如果接收命名返回值作為參數(shù)的話,那么命名返回值在延遲執(zhí)行的函數(shù)中訪問到,這樣就能將measure函數(shù)改造成記錄入?yún)⒑头祷刂档墓ぞ吆瘮?shù)。

下面的示例是引用《go 語言程序設(shè)計》中的代碼段:

func bigSlowOperation() {
  defer trace("bigSlowOperation")() // don't forget the extra parentheses
  // ...lots of work…
  time.Sleep(10 * time.Second) // simulate slow
  operation by sleeping
}
func trace(msg string) func() {
  start := time.Now()
  log.Printf("enter %s", msg)
  return func() { 
    log.Printf("exit %s (%s)", msg,time.Since(start)) 
  }
}

可以想象,將代碼延遲在函數(shù)的入口和出口使用是非常有用的功能,尤其是在調(diào)試代碼的時候。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

您可能感興趣的文章:
  • Golang學(xué)習(xí)筆記之延遲函數(shù)(defer)的使用小結(jié)
  • Go語言中的延遲函數(shù)defer示例詳解
  • golang中defer的關(guān)鍵特性示例詳解
  • golang中defer的使用規(guī)則詳解
  • Golang巧用defer進(jìn)行錯誤處理的方法
  • 總結(jié)Go語言中defer的使用和注意要點
  • GO語言Defer用法實例分析
  • GO語言延遲函數(shù)defer用法分析

標(biāo)簽:吐魯番 許昌 德宏 東營 常州 曲靖 保定 貴州

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《淺談go中defer的一個隱藏功能》,本文關(guān)鍵詞  淺談,中,defer,的,一個,隱藏,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《淺談go中defer的一個隱藏功能》相關(guān)的同類信息!
  • 本頁收集關(guān)于淺談go中defer的一個隱藏功能的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章