golang中defer的基本使用教程
前言
第一次看go基礎語法的時候,用使用到瞭defer。但是一直不知道它到底是什麼,有什麼用途。這幾天通過查詢、學習。算是對defer有瞭一點淺顯的認識。
1.什麼是defer
defer是go中一種延遲調用機制,defer後面的函數隻有在當前函數執行完畢後才能執行,通常用於釋放資源。
2.defer的特點
defer遵循先進後出的原則,類似於棧的結構。
補充下:為什麼要把defer設計成這種機制?
因為後申請的資源和可能對前面申請的資源有依賴。如果先將前面申請的資源釋放掉瞭。對於後面的資源可能會造成影響。所以先釋放後申請的資源,再釋放前面申請的資源。
3.defer什麼時間執行
前面說到,defer隻有在當前函數執行完畢後,才會執行。其實不太準確。
go中的return語句並不是原子性操作,一般是分為兩步:
- 將返回值賦值給一個變量
- 執行RET指令
defer就執行在1之後,2之前。
4.defer常見的坑
1.輸出是多少?
x := 10 defer func(a int) { fmt.Println(a) }(x) x++
答案:
為什麼?
因為defer後面的函數在入棧的時候保存的是入棧那一刻的值,而當時x的值是10,所以後期對x修改,並不會影響棧內函數的值。
2.輸出多少
x := 10 defer func(a *int) { fmt.Println(*a) }(&x) x++
答案:
為什麼?
這裡defer後面函數入棧的時候存入的執行變量x的指針。所以,後期x值改變的時候,輸出結果也會改變。
3.輸出多少
func test()(x int) { x = 10 defer func() { x++ }() return x }
答案:
為什麼?
之前我們說過,return並不是原子性操作,是通過一個變量賦值和ret指令來完成的。
而上述例子中,是具名函數。即返回值帶有名字。這樣我們在執行defer的時候相當於修改瞭返回值的值。所以為11
看到這裡,博主想到瞭閉包。和閉包有沒有關系呢?
4.輸出什麼
func test1() int { x := 10 defer func() { x++ }() // ans = x // -------- defer x = x+1 // return x return x }
答案:
為什麼?
還是return語句的原因,博主已經在代碼中給出提示。可見,非具名函數不會受到相應的影響。
對於defer暫時理解瞭這些,下次再見。
總結
到此這篇關於golang中defer基本使用的文章就介紹到這瞭,更多相關go defer使用內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Golang之defer 延遲調用操作
- Golang 的defer執行規則說明
- 聊聊golang中多個defer的執行順序
- Golang中panic的異常處理
- Go defer 原理和源碼剖析(推薦)