日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Golang語言中的Defer怎么使用?

[[404327]]

 01介紹

在 Golang 語言中,我們可以在函數(shù)(自定義和部分內(nèi)置)或方法中使用 defer 關(guān)鍵字注冊延遲調(diào)用(一個或多個),多個延遲調(diào)用的執(zhí)行順序是先進后出(FILO)。并且不會受到函數(shù)執(zhí)行結(jié)束退出,顯式調(diào)用 return 和主動(或被動)觸發(fā) panic 的影響,注冊成功的所有延遲調(diào)用都會被執(zhí)行,除非 defer 注冊在 return 之后或者函數(shù)(或方法)調(diào)用 os.Exit(1)。

defer 注冊多個延遲調(diào)用,執(zhí)行順序是先進后出(FILO)。

示例代碼:

 
 
 
 
  1. func main () { 
  2.  defer func() { 
  3.   fmt.Println("A") 
  4.  }() 
  5.  
  6.  defer func() { 
  7.   fmt.Println("B") 
  8.  }() 
  9.  
  10.  fmt.Println("main goroutine run over") 
  11.  
  12.  // panic("this is a panic example") 
  13.  
  14.  // return 

defer 如果定義在 return 之后,它等于 defer 沒有注冊,將不會執(zhí)行。

示例代碼:

 
 
 
 
  1. func main () { 
  2.  fmt.Println("main") 
  3.  return 
  4.  defer func() { 
  5.   fmt.Println("A") 
  6.  }() 

defer 所在的函數(shù)或方法中,如果調(diào)用 os.Exit(1),defer 即便注冊,也不會執(zhí)行。

示例代碼:

 
 
 
 
  1. func main () { 
  2.  defer func() { 
  3.   fmt.Println("A") 
  4.  }() 
  5.  fmt.Println("main") 
  6.  os.Exit(1) 

defer 必須在函數(shù)和方法中才可以使用,并且 defer 后面必須是函數(shù)(自定義和部分內(nèi)置函數(shù))或方法,defer 函數(shù)的實參是值拷貝。

示例代碼

 
 
 
 
  1. func main () { 
  2.  a := 0 
  3.  defer func(num int) { 
  4.   fmt.Println("defer func()", num) 
  5.  }(a) 
  6.  a++ 
  7.  fmt.Println(a) 

02使用場景

使用關(guān)鍵字 defer 注冊的函數(shù)(自定義和部分內(nèi)置)或方法,因為不會受到函數(shù)執(zhí)行結(jié)束,顯式調(diào)用 return 和主動(或被動)觸發(fā) panic 的影響,通常會用于防止忘記釋放資源和捕獲 panic(同一 goroutine 中) 防止應(yīng)用程序崩潰退出的應(yīng)用場景。

示例代碼:

 
 
 
 
  1. func main () { 
  2.  f, err := os.OpenFile("text.txt", os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0755) 
  3.  if err != nil { 
  4.   fmt.Println(err) 
  5.  } 
  6.  defer f.Close() 
  7.  n, err := f.WriteString("this is a text file\t") 
  8.  if err != nil { 
  9.   fmt.Println(err) 
  10.  } 
  11.  fmt.Println(n) 

閱讀上面這段代碼,我們使用 defer 延遲調(diào)用釋放資源,防止忘記釋放資源(關(guān)閉文件或解鎖),通常 defer 會放在錯誤檢查之后。

示例代碼:

 
 
 
 
  1. func main () { 
  2.  defer func() { 
  3.   if err := recover(); err != nil { 
  4.    fmt.Println("this is a panic" ) 
  5.   } 
  6.  }() 
  7.  panic("this is a test panic") 
  8.  fmt.Println("main") 

閱讀上面這段代碼,我們使用 defer 配合 recover 函數(shù),用于攔截 panic(同一 goroutine 中),防止程序崩潰退出。

03注意事項

雖然使用 defer 具有可以用于防止忘記釋放資源和攔截 panic(同一 goroutine 中)防止應(yīng)用程序崩潰退出等好處。

但是 defer 也有副作用,它會使資源延遲釋放,defer 盡量不要再 for-loop 中使用,并且相比于未使用 defer 調(diào)用的函數(shù)(自定義和部分內(nèi)置)或方法,defer 也有一定的性能損耗,Golang 語言官方也在 golang 1.13 和 golang 1.14 中優(yōu)化了 defer 的性能。

相比于 defer 的性能損耗,defer 帶來的使代碼更加優(yōu)雅、可讀和健壯等優(yōu)勢,我認為 defer 綜合來看,利大于弊,它可以給 gopher 們帶來的收益比付出的代價更大。所以,我建議大家盡量使用 defer。

還有一點需要注意的是,我們不要使用 defer 調(diào)用有返回值的自定義函數(shù)或方法,返回值會丟失,可能會給應(yīng)用程序帶來意想不到的錯誤。

04總結(jié)

本文我們介紹了 defer 的執(zhí)行機制,使用場景和注意事項,并且給出了相應(yīng)的示例代碼。通常我們會在 Golang 語言開發(fā)中使用 defer 防止忘記釋放資源(關(guān)閉文件或解鎖)和捕獲 panic(同一 goroutine 中) 防止應(yīng)用程序崩潰退出。

本文轉(zhuǎn)載自微信公眾號「Golang語言開發(fā)?!梗梢酝ㄟ^以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系Golang語言開發(fā)棧公眾號。


網(wǎng)頁題目:Golang語言中的Defer怎么使用?
分享鏈接:http://www.dlmjj.cn/article/djeipjh.html