golang 中的閉包和defer

golang中的defer和閉包對很多初學者來說,有時候有很多坑,但是很多介紹的文章有寫的亂七八糟.放假了沒事可干,就稍微總結一下.

閉包

閉包有叫匿名函數(shù),使用閉包可以使我們的代碼更加優(yōu)雅簡潔,顧名思義匿名函數(shù)就是沒有名字的函數(shù).

func test() int {
    var i int
    f:=func() {
        time.Sleep(1*time.Second)
        i += 1 //閉包是通過指針傳遞的,所以對i的修改相當于修改指針指向的內容.
        fmt.Println(" i:", i)
    }
    f()
    f()
    fmt.Println(i)
    return i
}

注意上面的代碼,上面的代碼輸出

 i: 1
 i: 2
2
2

因為閉包中對a中的變量i是通過指針傳遞的,所以閉包里面對i的修改會直接修改i的值.

defer

func a() int {
    var i int
    defer add(i) //這里雖然defer是在return之前執(zhí)行,但是在定義的時候,
    // 已經將defer要執(zhí)行的函數(shù)壓入棧,所以傳遞給add的是var i int的i值.
        /*defer func(){
        add(i)
    }() */
    i += 100
    return i //return  0
}
func b() int {
    var i int
    defer func(){
        add(i)
    }()
    i += 100
    return i //return  0
}
 add(i int)  {
    i += 1
    fmt.Println(i)
    
}

分別考慮一下a b 函數(shù)的輸出

1 
100

這里會產生不同是因為,如果你在定義defer的時候,就要將defer后面的函數(shù)參數(shù)等入棧,等到ruturn之前的時候出棧執(zhí)行,a中是將i的拷貝直接入棧,b中通過一個閉包調用,實際上將i的指針傳遞給閉包,閉包讀取值拷貝給add.
另外我們經常說defer定義的順序跟執(zhí)行的順序相反也是因為棧中先入后出的原因.

返回值

上面主要說了defer 和閉包,defer 容易讓人混淆的地方其實是在處理返回值的時候.

func d() (i int) {
    i = 100
    defer func() {
        i += 1
    }()
    return 5 // 這里返回之前相當于 i=5 執(zhí)行defer return i,所以defer中通過閉包給i++ 相當于{i=5 ,i++,return i}
}

func b() int {
    var i int
    defer func() {
        i += 1
    
    }()
    i += 100

    return i //這里相當于a=i defer return a 所以defer中閉包i++ 相當于{a=i i++ return a}
}

考慮一下上面2個函數(shù)的返回值,

100
6

b函數(shù)中返回retrun i 這個語句相當于如下

  • a=i(這里i值為100) //因為沒有定義返回值名,會定義一個int 的值保存i返回.
  • defer定義的函數(shù)出棧,然后執(zhí)行.在b中通過閉包對i進行了+1
  • return a
    所以返回值是100而不是101,因為在第一步a的值是100
    d 函數(shù)中return 5 這個語句相當于如下
  • i=5 //因為d函數(shù)中定義了返回值i
  • defer定義的函數(shù)出棧,然后執(zhí)行.在b中通過閉包對i進行了+1
  • return i
    所以返回值是6而不是5.

總結

其實理解defer 閉包這些只要理解以下幾點就會徹底明白

  1. 閉包是通過指針操作母函數(shù)中的變量
  2. defer 定義的過程就相當生成一個函數(shù)體然后將它壓入棧,等到return的時候出棧執(zhí)行
  3. defer 執(zhí)行是在return 之前執(zhí)行。這里要注意的是如果沒有聲明返回變量,需要先聲明一個返回值然后賦值給它返回。
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • Lua 5.1 參考手冊 by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 14,243評論 0 38
  • 第2章 基本語法 2.1 概述 基本句法和變量 語句 JavaScript程序的執(zhí)行單位為行(line),也就是一...
    悟名先生閱讀 4,536評論 0 13
  • 人或許在一個月的時間里會有那么幾天需要像魚兒一樣浮出水面,只是好好的呼吸。今天被許多要做的事情給嚇卻了。 ...
    TS小西閱讀 294評論 2 1
  • 2018今日閑情:前陣子,我和新婚妻子一起飛抵廈門,準備在這座風景秀麗蜚聲內外的城市拍攝婚紗照彩圖。 到酒店時已經...
    米其琳閱讀 8,832評論 0 3
  • 如果可以,請選擇這樣的生活
    姑娘XX閱讀 192評論 0 1

友情鏈接更多精彩內容