go語(yǔ)言中的defer關(guān)鍵字
我是誰(shuí)
defer
- 顧名思義翻譯過(guò)來(lái)叫 延遲, 所以我們通常稱呼 defer func()
這樣 defer
后面緊跟的函數(shù)為 延遲函數(shù).
作者注: 不過(guò)從實(shí)際應(yīng)用來(lái)講, 延遲函數(shù)通常用來(lái)做一些函數(shù)最終返回前的一些收尾工作, 所以稱呼為收尾函數(shù)其實(shí)更貼切.
三圍幾何
defer
有其獨(dú)特的一面, 了解其個(gè)性, 才能更好的下手。
延遲性
顧名思義, 既然叫延遲函數(shù), 那么肯定具備延遲性.
我們來(lái)看看怎么個(gè)延遲法,
defer_defer.go
// defer_defer.go package main import ( "fmt" ) func main() { foo() } func foo() { fmt.Println(1) defer fmt.Println(2) fmt.Println(3) } // go run defer_defer.go // 1 // 3 // 2
可以看到 defer
定義的延遲函數(shù)最后才執(zhí)行.
再來(lái)個(gè)例子, 如果一個(gè)函數(shù)內(nèi)出現(xiàn)多個(gè)延遲函數(shù), 延遲函數(shù)的執(zhí)行順序又是怎么樣的呢?
defer_filo.go
// defer_filo.go package main import ( "fmt" ) func main() { foo() } func foo() { defer fmt.Println(1) defer fmt.Println(2) defer fmt.Println(3) } // go run defer_filo.go // 3 // 2 // 1
可以看到先定義的延遲函數(shù)后執(zhí)行, 后定義的延遲函數(shù)先執(zhí)行, 符合棧 (stack) 的先進(jìn)后出 (FILO) 原則.
影響性
直接看代碼,
defer_impact.go
// defer_impact.go package main import ( "fmt" ) func main() { fmt.Println(foo()) } func foo() (result int) { defer func() { result++ }() return 0 } // go run defer_defer.go // 1
結(jié)果是不是跟想象有點(diǎn)不一樣? 上述 foo()
可以改寫為下:
func foo() (result int) { result = 0 result++ return }
go 中的 return
語(yǔ)句不是原子操作.
go 中 return
語(yǔ)句的操作過(guò)程為:
- 設(shè)置返回值
- 執(zhí)行延遲函數(shù)
- 真正
return
所以延遲函數(shù)會(huì)影響主函數(shù)的返回值, 當(dāng)然還要區(qū)分具名返回值/匿名返回值, 后話再說(shuō).
確定性
延遲函數(shù)的參數(shù)值, 在延遲函數(shù)首次出現(xiàn)時(shí)就確定了, 不受后續(xù)操作的影響.
我們來(lái)個(gè)例子:
defer_parameters.go
// defer_parameters.go package main import ( "fmt" ) func main() { foo() } func foo() { number := 1 defer fmt.Println(number) number = 2 return } // go run defer_parameters.go // 1
能做啥
- 打開數(shù)據(jù)鏈接, 要記得關(guān)閉, 可以用
defer
- 操作完內(nèi)存資源, 要記得釋放, 可以用
defer
- 想改變主函數(shù)的具名返回值, 可以用
defer
- 通常不會(huì)這么干 - 想奇淫技巧, 可以用
defer
- 偶爾 show 偶爾爽, 一直 show 一直爽 - 想搞事情, 可以用
defer
- 請(qǐng)自行確保生命和財(cái)產(chǎn)安全 - ...
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接
相關(guān)文章
Go語(yǔ)言常見(jiàn)錯(cuò)誤之a(chǎn)ny沒(méi)傳遞任何信息解決分析
Go語(yǔ)言,由于其高效強(qiáng)大的并行處理能力和優(yōu)雅簡(jiǎn)單的設(shè)計(jì)哲學(xué),一直以來(lái)都是編程世界的寵兒,然而,對(duì)于一些Go新手和甚至熟悉Go的程序員也可能會(huì)遇到一個(gè)常見(jiàn)的錯(cuò)誤:?any沒(méi)傳遞任何信息,那么,如何規(guī)避這個(gè)錯(cuò)誤,本文將揭示其中的秘密2024-01-01GO將mysql?中?decimal?數(shù)據(jù)類型映射到?protobuf的操作方法
這篇文章主要介紹了go如何優(yōu)雅地將?mysql?中?decimal?數(shù)據(jù)類型映射到?protobuf,本文主要展示一下在 protobuf中 float與double的一個(gè)區(qū)別,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09Go語(yǔ)言計(jì)算兩個(gè)經(jīng)度和緯度之間距離的方法
這篇文章主要介紹了Go語(yǔ)言計(jì)算兩個(gè)經(jīng)度和緯度之間距離的方法,涉及Go語(yǔ)言相關(guān)數(shù)學(xué)函數(shù)的使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-02-02Go語(yǔ)言變量與基礎(chǔ)數(shù)據(jù)類型詳情
Go 是靜態(tài)(編譯型)語(yǔ)言,是區(qū)別于解釋型語(yǔ)言的弱類型語(yǔ)言(靜態(tài):類型固定,強(qiáng)類型:不同類型不允許直接運(yùn)算),下面文章將對(duì)其進(jìn)行詳細(xì)介紹,需要的朋友可以參考一下2021-09-09Go Uber靜態(tài)分析工具NilAway使用初體驗(yàn)
這篇文章主要介紹了Go Uber靜態(tài)分析工具NilAway使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01golang 如何獲取pem格式RSA公私鑰長(zhǎng)度
這篇文章主要介紹了golang 如何獲取pem格式RSA公私鑰長(zhǎng)度操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12Go語(yǔ)言中同一個(gè)package中函數(shù)互相調(diào)用為undefined的解決
這篇文章主要介紹了Go語(yǔ)言中同一個(gè)package中函數(shù)互相調(diào)用為undefined的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03Go語(yǔ)言中零拷貝的原理與實(shí)現(xiàn)詳解
零拷貝是相對(duì)于用戶態(tài)來(lái)講的,即數(shù)據(jù)在用戶態(tài)不發(fā)生任何拷貝,那么零拷貝的原理是什么,又是如何實(shí)現(xiàn)的呢,下面小編就來(lái)和大家詳細(xì)聊聊吧2023-08-08