這篇文章主要介紹go語言defer怎么用,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
創(chuàng)新互聯(lián)建站專注于赤峰企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站建設(shè),商城網(wǎng)站建設(shè)。赤峰網(wǎng)站建設(shè)公司,為赤峰等地區(qū)提供建站服務(wù)。全流程按需定制開發(fā),專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)建站專業(yè)和態(tài)度為您提供的服務(wù)go語言defer的用法:1、defer語句在函數(shù)返回之前或函數(shù)中的return語句之后執(zhí)行;2、多個(gè)defer語句的執(zhí)行順序是逆序執(zhí)行;3、在panic語句后的defer語句不執(zhí)行。
用法介紹:
defer是Go語言中的延遲執(zhí)行語句,用來添加函數(shù)結(jié)束時(shí)執(zhí)行的代碼,常用于釋放某些已分配的資源、關(guān)閉數(shù)據(jù)庫連接、斷開socket連接、解鎖一個(gè)加鎖的資源。Go語言機(jī)制擔(dān)保一定會(huì)執(zhí)行defer語句中的代碼。
其它語言中也有類似的機(jī)制,比如Java、C#語言里的finally語句,C++語言里的析構(gòu)函數(shù)(Destructor)可以起類似的作用,C++語言機(jī)制擔(dān)保在對(duì)象被銷毀前一定會(huì)執(zhí)行析構(gòu)函數(shù)中的代碼。C++中的析構(gòu)函數(shù)析構(gòu)的是對(duì)象,Go中的defer析構(gòu)的是函數(shù)。
一、defer語句執(zhí)行時(shí)機(jī)
defer語句在函數(shù)返回之前 或者 函數(shù)中 return語句(return語句可能調(diào)用另一個(gè)函數(shù)) 之后執(zhí)行。示例代碼:
package main import ( "fmt" ) func main() { fmt.Println(deferReturn()) } func deferReturn() (ret int) { defer func() { ret++ }() return 10 }
上述代碼打印出來的值是:11。 defer語句 匿名函數(shù)中的“ret++” 對(duì)返回值 10 加 1 變成了 11。再來看一個(gè)defer語句出現(xiàn)在return語句之后的代碼:
func returnDefer() (ret int) { return 0 defer func() { ret++ ret++ }() return 1 }
上述returnDefer函數(shù)的返回值是:0。原因是defer語句還沒有添加上代碼執(zhí)行到"return 0"函數(shù)就返回了,因此defer語句就沒有執(zhí)行。
二、多個(gè)defer語句的執(zhí)行順序是逆序執(zhí)行
當(dāng)出現(xiàn)多條 defer 語句時(shí)以逆序執(zhí)行(類似棧,即后進(jìn)先出)。示例代碼:
func deferSample() { for i := 0; i < 5; i++ { defer fmt.Printf("%d ", i) } }
上述代碼將會(huì)輸出:4 3 2 1 0
三、defer與panic
1、在panic語句后面的defer語句不被執(zhí)行
示例代碼:
func panicDefer() { panic("panic") defer fmt.Println("defer after panic") }
上述代碼的輸出如下:
panic: panic goroutine 1 [running]: main.panicDefer() E:/godemo/testdefer.go:17 +0x39 main.main() E:/godemo/testdefer.go:13 +0x20 Process finished with exit code 2
可以看到 defer 語句沒有執(zhí)行。
2、在panic語句前的defer語句會(huì)被執(zhí)行
示例代碼:
func deferPanic() { defer fmt.Println("defer before panic") panic("panic") }
上述代碼的輸出如下:
defer before panic panic: panic goroutine 1 [running]: main.deferPanic() E:/godemo/testdefer.go:19 +0x95 main.main() E:/godemo/testdefer.go:14 +0x20 Process finished with exit code 2
defer 語句輸出了內(nèi)容。
Go中的panic類似其它語言中的拋出異常,panic后面的代碼不再執(zhí)行(panic語句前面的defer語句會(huì)被執(zhí)行)。
四、return 的實(shí)現(xiàn)邏輯
1、第一步給返回值賦值(若是有名返回值直接賦值,匿名返回值 則 先聲明再 賦值) ;
2、第二步調(diào)用RET返回指令并傳入返回值,RET會(huì)檢查是否存在defer語句,若存 在就先逆序插播 defer語句 ;
3、最后 RET 攜帶返回值退出函數(shù) 。
可以看出 , return 不是一個(gè)原子操作,函數(shù)返回值與 RET 返回值并不一定一致。
五、defer、 return、返回值三者順序
defer、 return、返回值 三者的執(zhí)行順序是 : return 最先給返回值賦值;接著 defer 開始執(zhí)行一些收尾工作;最后 RET 指令攜帶返回值退出函數(shù)。
以上是“go語言defer怎么用”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!