1:延遲函數(shù)傳遞的參數(shù)是值
func deferTest() { var a = 1 defer fmt.Println(a) a = 2 return }
結(jié)論:延遲函數(shù) fmt.Println(a) 的參數(shù)在 defer 語(yǔ)句出現(xiàn)的時(shí)候就已經(jīng)確定下來(lái)了,所以不管后面如何修改 a 變量,都不會(huì)影響延遲函數(shù)
2:延遲函數(shù)傳遞的參數(shù)是地址
func deferTest() { var arr = [3]int{1, 2, 3} defer printTest(&arr) arr[0] = 4 return } func printTest(array *[3]int) { for i := range array { fmt.Println(array[i]) } }
結(jié)論:延遲函數(shù) printTest() 的參數(shù)在 defer 語(yǔ)句出現(xiàn)的時(shí)候就已經(jīng)確定下來(lái)了,即為數(shù)組的地址,延遲函數(shù)執(zhí)行的時(shí)機(jī)是在 return 語(yǔ)句之前,所以對(duì)數(shù)組的最終修改的值會(huì)被打印出來(lái)。
3:延遲函數(shù)可能會(huì)影響函數(shù)的返回值
fmt.Println(deferTest) func deferTest() (result int) { i := 1 defer func() { result = 2 }() return i }
結(jié)論:函數(shù)的 return 語(yǔ)句并不是原子級(jí)的,實(shí)際的執(zhí)行過(guò)程為為設(shè)置返回值—>ret,defer 語(yǔ)句是在返回前執(zhí)行,所以返回過(guò)程是:「設(shè)置返回值—>執(zhí)行defer—>ret」。所以 return 語(yǔ)句先把 result 設(shè)置成 i 的值(1),defer 語(yǔ)句中又把 result設(shè)置為 2 ,所以最終返回值為 2
4:defer需要定義在panic前
func panicBeforeDefer() { panic("a") defer func() { fmt.Println("b") }() } func panicAfterDefer() { defer func() { fmt.Println("b") }() panic("a") }
結(jié)論:代碼執(zhí)行到了painc之后再執(zhí)行的defer,然后按照defer的先進(jìn)后出的順序執(zhí)行defer,最后才執(zhí)行panic。那為什么panic時(shí)會(huì)執(zhí)行defer,可以看下這段代碼就很清楚了。
func gopanic(e interface{}) { gp := getg() ... var p _panic p.arg = e p.link = gp._panic gp._panic = (*_panic)(noescape(unsafe.Pointer(&p))) for { d := gp._defer if d == nil { break } ... } }
5:先判斷err,再defer釋放資源
func openFile() { file, err := os.Open("txt") if err != nil { return } defer file.Close() }
結(jié)論:獲取文件資源的時(shí)候會(huì)返回err,如果我們?cè)诤罄m(xù)需要進(jìn)行defer釋放文件資源時(shí),這里需要對(duì)err進(jìn)行判斷。因?yàn)槿绻@取文件資源失敗的時(shí)候不需要進(jìn)行釋放,也避免了沒(méi)獲取到資源可能導(dǎo)致的釋放函數(shù)執(zhí)行錯(cuò)誤。
6:os.Exit時(shí)defer不會(huì)被執(zhí)行
func deferExit() { defer func() { fmt.Println("exit") }() os.Exit(1) }
結(jié)論:上面代碼中的defer不會(huì)得到執(zhí)行,因?yàn)閛s.Exit()用于立即中止程序,不可能恢復(fù)或運(yùn)行延遲清理語(yǔ)句,不像panic會(huì)去找goroutine的defer鏈表。
審核編輯:劉清
-
defer
+關(guān)注
關(guān)注
0文章
2瀏覽量
1170
原文標(biāo)題:【Golang】defer的這些坑,你遇到過(guò)嗎?
文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
你在使用WI-FI6模塊PTR7002時(shí)遇到過(guò)哪些通信問(wèn)題?歡迎分享解決方案!
這些CAD問(wèn)題你遇到過(guò)嗎?CAD常見(jiàn)問(wèn)題匯總解答!
使用openocd下載程序時(shí)報(bào)錯(cuò)有人遇到過(guò)嗎
你是否遇到過(guò)某個(gè)MCU串口不夠的情況
用J_link下載程序是遇到的問(wèn)題,有哪個(gè)大佬遇到過(guò),怎么解決的?
電瓶修復(fù)—電池負(fù)極閉孔你遇到過(guò)沒(méi)?
PCB設(shè)計(jì)遇到過(guò)孔stub如何解決
使用Redis時(shí)可能遇到哪些「坑」?

這17種焊接陷阱,你遇到過(guò)多少?

這17種焊接陷阱,你遇到過(guò)多少?

【廣凌房產(chǎn)】高校公用房管理中的這些問(wèn)題,你遇到過(guò)嗎?

【電路設(shè)計(jì)】這17種焊接陷阱,你遇到過(guò)多少?

Modbus TCP通信的那些坑!你遇到過(guò)幾個(gè)?

評(píng)論