xdm , 不知道你們是否有使用過 defer ,這種語法在是 go 特有的,用起來真是爽的不要不要的
很多時候,我們在使用一些新東西,出現一些莫名其妙的現象或者是結果的時候,我們總會認為,這個東西不友好, 這個東西好坑,好奇怪
其實我們是要弄明白其中的注意點,原理,當出現所謂的奇怪現象的時候,處理起來就會得心應手得多
xdm,這裡準備瞭如下注意事項,請查收
案例 1
這裡先統一說明一下 defer 是幹什麼的?
是 GO 中的一個關鍵字
這個關鍵字,我們一般用在釋放資源,在 return
前會呼叫他
如果程式中有多個 defer
,defer 的呼叫順序是按照類似棧的方式,後進先出 LIFO
的 , 具體的 defer 實現原理可以檢視我的歷史文章 GO 中 defer的實現原理
先來看一個 demo,猜一猜他的輸出是什麼?
寫一個 defer 和 defer 在一起的 輸入輸出順序 demo
- 簡單寫 4 個函式,分別應用到 defer 上
func test1() {
fmt.Println("test 1")
}
func test2() {
fmt.Println("test 2")
}
func test3() {
fmt.Println("test 3")
}
func test4() {
fmt.Println("test 4")
}
func main() {
defer test1()
defer test2()
defer test3()
defer test4()
}
執行上述程式碼,我們期望的結果是什麼呢?
test 1
test 2
test 3
test 4
還是
test 4
test 3
test 2
test 1
小夥伴們感興趣的可以執行一下,結果是 第二種,defer 我們可以理解為是一個入棧操作,先進後出
入棧 : test1(),test2(),test3(),test4()
出棧 : test4(),test3(),test2(),test1()
案例 2
上面我們知道 defer 和 defer 的順序是按照棧的順序來,那麼我們下面來看看 defer 和 return 的順序又是什麼樣子的 ?
- 簡單寫 一個用於 return 的函式和 用於 defer 的函式
func testDefer() {
fmt.Println("testDefer")
}
func testReturn() int {
fmt.Println("testReturn")
return 1
}
func myTest() int {
defer testDefer()
return testReturn()
}
func main() {
myTest()
}
再來猜測一下上述編碼會是如何執行的呢
是這樣的嗎?
testDefer
testReturn
還是這樣的 ?
testReturn
testDefer
結果仍然是第二種,透過上述編碼我們可以看出來 defer 後面的語句 是晚執行的, return 後面的語句是先執行的
那麼如果是 多個 defer 和 return 放在一起呢?
xdm ,我們們舉一反三了,那肯定還是 return 先執行,defer 按照棧的順序執行
案例 3
這個案例我們們加上簡單的計算,看看效果如何
- 簡單些一下帶有計算的 defer
func testDefer(num int)(res int){
defer func(){
res = num + 3
}()
return num
}
func main(){
res := testDefer(5)
fmt.Println(res)
}
上述編碼執行後會是什麼效果呢
是 5 嗎? 是 8 嗎?反正肯定不是 3 吧
思考一下,按照上面案例 1 的邏輯,結果是 8
老鐵,沒毛病, num 透過 testDefer 函式傳值,賦值 為 5 ,return num
的時候,返回值是 5,再執行 defer 語句, 5+3 就是 8
好了,今天就到這裡,感興趣的朋友也可以玩起來
歡迎點贊,關注,收藏
朋友們,你的支援和鼓勵,是我堅持分享,提高質量的動力
好了,本次就到這裡
技術是開放的,我們的心態,更應是開放的。擁抱變化,向陽而生,努力向前行。
我是阿兵雲原生,歡迎點贊關注收藏,下次見~