對閉包的具體定義有不少種說法,這些說法大致能夠分爲兩類: 說法1:閉包是符合必定條件的函數,好比閉包是在其詞法上下文中引用了自由變量的函數。 說法2:閉包是由函數和與其相關的引用環境組合而成的實體。好比在實現深約束時,須要建立一個能顯式表示引用環境的東西,並將它與相關的子程序捆綁在一塊兒,這樣捆綁起來的總體被稱爲閉包。html
具體能夠看這個文章《閉包的概念、形式與應用》linux
支持了閉包的語言有不少,這裏以go語言爲例。閉包
package main import "fmt" func add() func(int) int { ---add()函數返回一個匿名函數 sum := 0 ---add()內部的局部變量 return func(x int) int { ----返回一個匿名函數,下文提到的匿名函數均指該函數 sum += x ----函數內部實現sum+參數x return sum } } func main() { pos, neg := add(), add() ----將兩個add()函數的返回(上面的匿名函數)分別賦給兩個變量,也就是說這兩個變量表明的其實就是兩個函數 for i := 0; i < 10; i++ { fmt.Println( pos(i), ----至關於上面匿名函數調用,參數爲i neg(-2*i), --------至關於上面匿名函數調用,參數爲-2*i ) } }
咱們來看看執行結果:函數
0 0 1 -2 3 -6 6 -12 10 -20 15 -30 21 -42 28 -56 36 -72 45 -90
從結果能夠看出來,在循環裏面每次順序調用pos, neg兩個函數,即連續調用兩次上述匿名函數。spa
第一次循環體執行以後結果都爲0就不說了;第二次循環體執行時調用pos時參數爲i=1,通過調用pos函數(內部對局部變量sum+i)返回的sum變爲1;調用neg時參數爲i=1,通過調用pos函數(內部對局部變量sum+(-2*i))返回的sum變爲-2。code
注意,調用neg時並無由於調用pos使sum變爲1,而在sum=1的基礎上作sum+(-2*i),sum還是以0值進行計算。htm
第三次循環體執行時,pos和neg內部分別以本身上次調用返回的sum做爲新值進行計算。get
pos和neg內部的sum是互相隔離的,在pos調用以後調用neg,會將sum變爲neg以前對應的sum值;neg調用以後調用pos,一樣也會將sum變爲pos以前對應的值。這也就證明了上面關於閉包的說法2更確切一點。即閉包是函數和與其相關的引用環境打包以後的一個總體string
---未完待續---it