go語言中defer實例講解

今天看李文周老師的博客講解go語言defer關鍵字,我試着解讀下兩個實例

理論

defer執行時機

在Go語言的函數中return語句在底層並不是原子操作,它分爲給返回值賦值和RET指令兩步。而defer語句執行的時機就在返回值賦值操作後,RET指令執行前。具體如下圖所示:
在這裏插入圖片描述

實例一:

func f1() int {
	x := 5
	defer func() {
		x++
	}()
	return x
}

func f2() (x int) {
	defer func() {
		x++
	}()
	return 5
}

func f3() (y int) {
	x := 5
	defer func() {
		x++
	}()
	return x
}
func f4() (x int) {
	defer func(x int) {
		x++
	}(x)
	return 5
}
func main() {
	//分析過程:定義x = 5,然後將返回值int賦值爲x也就是5,此時defer函數執行,x變爲6,但此時int值並不受影響(可以理解爲兩塊內存地址),再執行RET所以返回值爲5
	fmt.Println(f1())	// 5
	//分析過程:調用f2函數,將y返回值x 賦值爲5,此時y執行defer函數將x 變爲6,同時返回值變爲6(可以理解爲同一塊內存地址),再執行RET所以返回值爲6
	fmt.Println(f2())	// 6
	//分析過程:定義x = 5,然後將返回值y賦值爲x也就是5,此時defer函數執行,x變爲6,但此時y值並不受影響(可以理解爲兩塊內存地址),再執行RET所以返回值爲5
	fmt.Println(f3())	// 5
	//分析過程:defer註冊要延遲執行的函數時該函數所有的參數都需要確定其值,因此在執行到defer時,x = 0。執行到return時,將 返回值x賦值爲5,此時defer函數中x 變爲1,但對返回值x沒有影響(可以理解爲兩塊內存地址), 再執行RET所以返回值爲5
	fmt.Println(f4())	// 5
}

實例二:

package main

import "fmt"

func calc(index string, a, b int) int {
ret := a + b
fmt.Println(index, a, b, ret)
return ret
}

func main() {
x := 1
y := 2
defer calc("AA", x, calc("A", x, y))	//在執行到此處,因爲y參數沒有確定,因此首先會調用calc函數,運算得出y值。
x = 10
defer calc("BB", x, calc("B", x, y))	//在執行到此處,因爲y參數沒有確定,因此首先會調用calc函數,運算得出y值。
y = 20
}

執行結果

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章