首頁 > 軟體

golang中defer的基本使用教學

2022-06-29 18:02:41

前言

第一次看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使用內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com