golang自學之路(defer壓棧)10

defer fmt.Println("a")
defer fmt.Println("b")
defer fmt.Println("c")

輸出:

c
b
a

先進後出,後進先出

總結:不管有沒有異常,defer都會在函數出棧的前一步執行,所有隻要函數沒有出棧,defer修飾的都是會被執行的。

順序:函數內其它語句-defer語句-函數出棧

//例1:
func f() (result int) {
    defer func() {
        result++
    }()
    return 0
}
 
//例2:
func f() (r int) {
    t := 5
    defer func() {
        t = t + 5
    }()
    return t
}
 
//例3:
func f() (r int) {
    defer func(r int) {
        r = r + 5
    }(r)
    return 1
}


 

func f() (result int) {
    result = 0 //return語句不是一條原子調用,return xxx其實是賦值+ret指令
    func() { //defer被插入到return之前執行,也就是賦返回值和ret指令之間
        result++
    }()
    return
}
//所以這個返回值是1。
 
//再看例2,它可以改寫成這樣:
func f() (r int) {
    t := 5
    r = t //賦值指令
    func() { //defer被插入到賦值與返回之間執行,這個例子中返回值r沒被修改過
        t = t + 5
    }
    return //空的return指令
}
//所以這個的結果是5。
 
//最後看例3,它改寫後變成:
func f() (r int) {
    r = 1 //給返回值賦值
    func(r int) { //這裏改的r是傳值傳進去的r,不會改變要返回的那個r值
        r = r + 5
    }(r)
    return //空的return
}
//所以這個例子的結果是1

 

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