[轉] 函數編程之閉包漫談(Closure)

在函數編程中常常用到閉包。閉包是什麼,它是怎麼產生的及用來解決什麼問題呢。給出字面的定義 先:閉包是由函數及其相關的引用環境組合而成的實體(即:閉包=函數+引用環境)。這個從字面上很難理解,特別對於一直使用命令式語言進行編程的程序員 們。本文將結合實例代碼進行解釋。
函數是什麼
地球人都知道:函數只是一段可執行代碼,編譯後就「固化」了,每一個函數在內存中只有一份實例,獲得函數的入口點即可以執行函數了。在函數式編程語言中,函 數是一等公民(First class value:第一類對象,咱們不須要像命令式語言中那樣藉助函數指針,委託操做函數),函數能夠做爲另外一個函數的參數或返回值,能夠賦給一個變量。函數可 以嵌套定義,即在一個函數內部能夠定義另外一個函數,有了嵌套函數這種結構,便會產生閉包問題。如:
複製代碼
>>> def ExFunc(n):
     sum=n
     def InsFunc():
             return sum+1
     return InsFunc

>>> myFunc=ExFunc(10)
>>> myFunc()
11
>>> myAnotherFunc=ExFunc(20)
>>> myAnotherFunc()
21
>>> myFunc()
11
>>> myAnotherFunc()
21
>>>
複製代碼

在這段程序中,函數InsFunc是函數ExFunc的內嵌函數,而且是ExFunc函數的返回值。咱們注意到一個問題:內嵌函數InsFunc中 引用到外層函數中的局部變量sum,IronPython會這麼處理這個問題呢?先讓咱們來看看這段代碼的運行結果。當咱們調用分別由不一樣的參數調用 ExFunc函數獲得的函數時(myFunc(),myAnotherFunc()),獲得的結果是隔離的,也就是說每次調用ExFunc函數後都將生成並保存一個新的局部變量sum。其實這裏ExFunc函數返回的就是閉包。
程序員

引用環境
按照命令式語言的規則,ExFunc函數只是返回了內嵌函數InsFunc的地址,在執行InsFunc函數時將會因爲在其做用域內找不到sum變量而出 錯。而在函數式語言中,當內嵌函數體內引用到體外的變量時,將會把定義時涉及到的引用環境和函數體打包成一個總體(閉包)返回。如今給出引用環境的定義就 容易理解了:引用環境是指在程序執行中的某個點全部處於活躍狀態的約束(一個變量的名字和其所表明的對象之間的聯繫)所組成的集合。閉包的使用和正常的函 數調用沒有區別。
編程

因爲閉包把函數和運行時的引用環境打包成爲一個新的總體,因此就解決了函數編程中的嵌套所引起的問題。如上述代碼段中,當每次調用ExFunc函數 時都將返回一個新的閉包實例,這些實例之間是隔離的,分別包含調用時不一樣的引用環境現場。不一樣於函數,閉包在運行時能夠有多個實例,不一樣的引用環境和相同 的函數組合能夠產生不一樣的實例。
數組

Rise our ability!
相關文章
相關標籤/搜索