1. 程式人生 > >Golang中的匿名函式(閉包)

Golang中的匿名函式(閉包)

GO語言的匿名函式就是閉包,以下是《GO語言程式設計》中對閉包的解釋

 基本概念
閉包是可以包含自由(未繫結到特定物件)變數的程式碼塊,這些變數不在這個程式碼塊內或者
任何全域性上下文中定義,而是在定義程式碼塊的環境中定義。要執行的程式碼塊(由於自由變數包含
在程式碼塊中,所以這些自由變數以及它們引用的物件沒有被釋放)為自由變數提供繫結的計算環
境(作用域)。
 閉包的價值
閉包的價值在於可以作為函式物件或者匿名函式,對於型別系統而言,這意味著不僅要表示
資料還要表示程式碼。支援閉包的多數語言都將函式作為第一級物件,就是說這些函式可以儲存到
變數中作為引數傳遞給其他函式,最重要的是能夠被函式動態建立和返回。

 

重點來了,先看一段程式碼:

package main
import "fmt"

func adder() func(int) int{
    fmt.Println("this line exec")
    sum := 0
    return func(x int) int{
        fmt.Println("sum  = ",sum)
        sum += x
        return sum
    }
}

func main(){
    pos , neg := adder(),adder()
    for i:=0 ; i< 4
; i++ { fmt.Println(pos(i),neg(-2*i)) } }

執行結果如下:

this line exec
this line exec
sum = 0
sum = 0
0 0
sum = 0
sum = 0
1 -2
sum = 1
sum = -2
3 -6
sum = 3
sum = -6
6 -12

-----------------------------

從列印中可以看出,對於閉包而言,重要的是返回的匿名函式,對於在程式碼區域內的閉包,其閉包內的變數是未銷燬的,這也是sum的變數值儲存的原因,而且,sum = 0只是執行了一次。這也就是說,對於閉包而言,其初始化一次後,匿名函式內的變數就一直不被銷燬(程式碼區域內),每次執行閉包,閉包內的變數有儲存了上一次執行後的值。所以,看下邊程式碼:

func adder() func(int) int{
    fmt.Println("this line exec")
    sum := 0
    return func(x int) int{
        fmt.Println("sum  = ",sum)
        sum += x
        return sum
    }
}

func main(){
    pos := adder()
    for i:=0 ; i< 4; i++ {
        fmt.Println(pos(1))
    }
}

結果是:

this line exec
sum = 0
1
sum = 1
2
sum = 2
3
sum = 3
4

可以更清晰的瞭解。