拓撲學到golang的函數閉包

閉包

1,概念

閉包是函數式編程中一個重要的概念。要了解閉包,首先要先了解幾個數學中拓撲學的集合概念,閉集,開集,閉包。

閉集與開集

一般的,有a和b是已知實數,我們把集合[a,b],這樣的集合稱爲閉集,把(a,b)這樣的集合稱爲開集。

由以上結論,若設集合A = (a,b) ,b = {a,b}.這裏A是一個範圍,B是由兩個數構成的集合。那麼可以得到

A U B = [a, b] 是一個閉集。

通俗的講,開集 + 邊界 = 閉集

閉包

在上述基礎上,我們把A U B稱爲A的閉包,可見閉包是一個閉集。由此,我們可以知道閉包是包括開集及其邊界的一個集合。

2,函數編程中的閉包

函數編程中,我們把在函數內部聲明的函數叫做這個函數閉包。

基於閉包概念,可知函數的閉包應該包含函數與及其不包含的邊界。這種哲學反映在在了函數的變量上,閉包可以使用函數中的變量,而且是函數中的最終變量。說明閉包包含了函數裏面所有的運算,所以叫閉包嘛。

接下來看golang中閉包的長相

func main() {
    A()()
}
​
func A() func() {
    return func() {
        fmt.Print("這是一個閉包")
    }
}

從上面看,返回的函數就是函數A的閉包。

接下來需要與閉包概念統一,即閉包應包含函數A中的所有操作。

func main() {
    A()()
}
​
func A() func() {
    b := 1
    a := func() {
        fmt.Print("閉包中的變量", b)
    }
    b = 3
    return a 
}
// 閉包中的變量3

顯然可以理解成閉包需要包含函數A中的所有操作,所以這個b應該是函數執行完畢後的值,所以b需要是3

接下來再看一段代碼:

func main() {
    A()()
}
​
func A() func()func() {
    b := 1
    a := func() func(){
        b = 2
        return func() {
            fmt.Println("這是一個閉包", b)
        }
        b = 5
    }
    b = 3
    return a
}
//這是一個閉包5

閉包,對於A來說,func()func()纔是A的閉包,我們暫時不把閉包的閉包也是他的閉包拿出來講。如上的程序,func()func()的閉包是func(),func()中的這個b是從func()func()中拿的,那func()func()的變量就要去A中拿,所以出現了閉包中的變量就近原則。

通過上述基礎,我們知道了爲什麼閉包要這樣設計,那麼這樣的設計是怎麼做的呢?這個再網上有很多資料,包括作用域鏈,閉包與自定義變量的存儲再堆上,這些都是爲了實現閉包的設計。


如果有錯,歡迎指出。

郵箱:[email protected]

 

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