閉包可以在其定義的上下文中捕獲常量或變量。 即使定義這些常量和變量的原域已經(jīng)不存在,閉包仍然可以在閉包函數(shù)體內(nèi)引用和修改這些值。
Swift最簡(jiǎn)單的閉包形式是嵌套函數(shù),也就是定義在其他函數(shù)的函數(shù)體內(nèi)的函數(shù)。 嵌套函數(shù)可以捕獲其外部函數(shù)所有的參數(shù)以及定義的常量和變量。
下例為一個(gè)叫做makeIncrementor
的函數(shù),其包含了一個(gè)叫做incrementor
嵌套函數(shù)。 嵌套函數(shù)incrementor
從上下文中捕獲了兩個(gè)值,runningTotal
和amount
。 之后makeIncrementor
將incrementor
作為閉包返回。 每次調(diào)用incrementor
時(shí),其會(huì)以amount
作為增量增加runningTotal
的值。
func makeIncrementor(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0
func incrementor() -> Int {
runningTotal += amount
return runningTotal
}
return incrementor
}
makeIncrementor
返回類型為() -> Int
。 這意味著其返回的是一個(gè)函數(shù),而不是一個(gè)簡(jiǎn)單類型值。 該函數(shù)在每次調(diào)用時(shí)不接受參數(shù)只返回一個(gè)Int
類型的值。 關(guān)于函數(shù)返回其他函數(shù)的內(nèi)容,請(qǐng)查看函數(shù)類型作為返回類型。
makeIncrementor
函數(shù)定義了一個(gè)整型變量runningTotal
(初始為0) 用來(lái)存儲(chǔ)當(dāng)前跑步總數(shù)。 該值通過(guò)incrementor
返回。
makeIncrementor
有一個(gè)Int
類型的參數(shù),其外部命名為forIncrement
, 內(nèi)部命名為amount
,表示每次incrementor
被調(diào)用時(shí)runningTotal
將要增加的量。
incrementor
函數(shù)用來(lái)執(zhí)行實(shí)際的增加操作。 該函數(shù)簡(jiǎn)單地使runningTotal
增加amount
,并將其返回。
如果我們單獨(dú)看這個(gè)函數(shù),會(huì)發(fā)現(xiàn)看上去不同尋常:
func incrementor() -> Int {
runningTotal += amount
return runningTotal
}
incrementor
函數(shù)并沒(méi)有獲取任何參數(shù),但是在函數(shù)體內(nèi)訪問(wèn)了runningTotal
和amount
變量。這是因?yàn)槠渫ㄟ^(guò)捕獲在包含它的函數(shù)體內(nèi)已經(jīng)存在的runningTotal
和amount
變量而實(shí)現(xiàn)。
由于沒(méi)有修改amount
變量,incrementor
實(shí)際上捕獲并存儲(chǔ)了該變量的一個(gè)副本,而該副本隨著incrementor
一同被存儲(chǔ)。
然而,因?yàn)槊看握{(diào)用該函數(shù)的時(shí)候都會(huì)修改runningTotal
的值,incrementor
捕獲了當(dāng)前runningTotal
變量的引用,而不是僅僅復(fù)制該變量的初始值。捕獲一個(gè)引用保證了當(dāng)makeIncrementor
結(jié)束時(shí)候并不會(huì)消失,也保證了當(dāng)下一次執(zhí)行incrementor
函數(shù)時(shí),runningTotal
可以繼續(xù)增加。
注意:
Swift 會(huì)決定捕獲引用還是拷貝值。
您不需要標(biāo)注amount
或者runningTotal
來(lái)聲明在嵌入的incrementor
函數(shù)中的使用方式。
Swift 同時(shí)也處理runingTotal
變量的內(nèi)存管理操作,如果不再被incrementor
函數(shù)使用,則會(huì)被清除。
下面代碼為一個(gè)使用makeIncrementor
的例子:
let incrementByTen = makeIncrementor(forIncrement: 10)
上一篇:Swift存儲(chǔ)型屬性的初始賦值下一篇:Swift 反初始化