introduction
閉包可以用來在一個函式與一組「私有」變數之間建立關聯關係。在給定函式被多次呼叫的過程中,這些私有變數能夠保持其永續性。變數的作用域僅限於包含它們的函式,因此無法從其它程式代碼部分進行存取。不過,變數的生存期是可以很長,在一次函式呼叫期間所建立所生成的值在下次函式呼叫時仍然存在
example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package main
import "fmt"
func SaveAdd() func(int) int { var x int return func(add int) int { x += add return x } }
func main(){ f := SaveAdd() fmt.Println(f(1)) fmt.Println(f(100)) fmt.Println(f(1000)) }
|
[1] SaveAdd
函數的返回值為一個函數
[2] return
的匿名函數引用了函數外的變量x
,使得return
的這個匿名函數成為了閉包,而被綁定的x
變量會記得被調用的狀態,等待下次再被調用
[3] f
為一個被已執行函數賦值的變量
[4] f
的參數為[2]return
匿名函數的參數
result
因f
一直存在,其中的x
變量指向的值仍為同一塊內存空間,故保留了函數return
匿名函數對x
的操作並返回x
之值
換句話說 (python)
可將整個函數當成一個class
,對class
內部的函數來說
外部變量就相當於class
的屬性
內部的函數操作類屬性時,類屬性會改變,且會記住被操作的最後狀態,並等待下次被其他內部函數操作
1 2 3 4 5 6 7 8 9 10 11 12
| class outerFunction(): def __init__(self): self.outervar = 1
def inner_function(self,var): self.outervar += var
if __name__ == "__main__": f = outerFunction() print("outervar =",f.outervar) f.inner_function(2) print("outervar =",f.outervar)
|
result
f
物件並未消失,所以類屬性被內部類函數操作時,仍會記住其屬性狀態
檢測文件後綴名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| package main
import ( "strings" "fmt" )
func detect_extension(extension string) func(string string) string { return func(filename string) string { if strings.HasSuffix(filename,extension) == false { return filename + extension } return filename } }
func main(){ bmp := detect_extension(".bmp") jpg := detect_extension(".jpg") fmt.Println(bmp("test")) fmt.Println(bmp("test_2.bmp")) fmt.Println(jpg("TEST")) fmt.Println(jpg("TEST_2.jpg")) }
|
[1] 內部匿名函數引用了外部的變量extension
[2] 調用函數並綁定了extension
變量
[3] 對內部的匿名函數傳參
result
1 2 3 4
| test.bmp test_2.bmp TEST.jpg TEST_2.jpg
|
Reference
https://zh.wikipedia.org/wiki/%E9%97%AD%E5%8C%85_(%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6)