閉包
本節(jié)內容包括:
- 閉包表達式
- 尾隨閉包
- 值捕獲
- 閉包是引用類型
Swift 中的閉包與 C 和 Objective-C 中的代碼塊(blocks)以及其他一些編程語言中的 lambdas 函數比較相似揪利。
閉包表達式
嵌套函數 是一個在較復雜函數中方便進行命名和定義自包含代碼模塊的方式。當然翔始,有時候撰寫小巧的沒有完整定義和命名的類函數結構也是很有用處的,尤其是在您處理一些函數并需要將另外一些函數作為該函數的參數時案淋。
閉包表達式是一種利用簡潔語法構建內聯(lián)閉包的方式擎浴。 閉包表達式提供了一些語法優(yōu)化,使得撰寫閉包變得簡單明了丰介。 下面閉包表達式的例子通過使用幾次迭代展示了sorted函數定義和語法優(yōu)化的方式位谋。 每一次迭代都用更簡潔的方式描述了相同的功能山析。
sorted函數
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
func backwards(s1: String, s2: String) -> Bool {
return s1 > s2
}
var reversed = sorted(names, backwards)
// reversed 為 ["Ewa", "Daniella", "Chris", "Barry", "Alex"]
閉包表達式語法
閉包表達式語法有如下一般形式
{ (parameters) -> returnType in
statements
}
之前函數對應的例子為:
reversed = sorted(names, { (s1: String, s2: String) -> Bool in
return s1 > s2
})
根據上下文推斷類型
任何情況下,通過內聯(lián)閉包表達式構造的閉包作為參數傳遞給函數時掏父,都可以推斷出閉包的參數和返回值類型,這意味著您幾乎不需要利用完整格式構造任何內聯(lián)閉包秆剪。
reversed = sorted(name, {s1,s2 in return s1 > s2})
單表達式閉包隱式返回
單行表達式閉包可以通過隱藏return關鍵字來隱式返回單行表達式的結果
reversed = sorted(names, {s1, s2 in s1 > s2})
參數名稱縮寫
Swift 自動為內聯(lián)函數提供了參數名稱縮寫功能赊淑,您可以直接通過$0,$1,$2來順序調用閉包的參數。
如果您在閉包表達式中使用參數名稱縮寫仅讽,您可以在閉包參數列表中省略對其的定義陶缺,并且對應參數名稱縮寫的類型會通過函數類型進行推斷。 in關鍵字也同樣可以被省略洁灵,因為此時閉包表達式完全由閉包函數體構成:
reversed = sorted(names, {$0 > $1})
運算符函數
實際上還有一種更簡短的方式來撰寫上面例子中的閉包表達式饱岸。 Swift 的String類型定義了關于大于號 (>) 的字符串實現(xiàn),其作為一個函數接受兩個String類型的參數并返回Bool類型的值徽千。 而這正好與sorted函數的第二個參數需要的函數類型相符合苫费。 因此,您可以簡單地傳遞一個大于號双抽,Swift可以自動推斷出您想使用大于號的字符串函數實現(xiàn):
reversed = sorted(names , >)
尾隨閉包
如果您需要將一個很長的閉包表達式作為最后一個參數傳遞給函數百框,可以使用尾隨閉包來增強函數的可讀性。 尾隨閉包是一個書寫在函數括號之后的閉包表達式牍汹,函數支持將其作為最后一個參數調用铐维。
reversed = sorted(names) { $0 > $1 }
捕獲值
閉包可以在其定義的上下文中捕獲常量或變量柬泽。 即使定義這些常量和變量的原域已經不存在,閉包仍然可以在閉包函數體內引用和修改這些值嫁蛇。
Swift最簡單的閉包形式是嵌套函數锨并,也就是定義在其他函數的函數體內的函數。 嵌套函數可以捕獲其外部函數所有的參數以及定義的常量和變量睬棚。
閉包是引用類型
無論您將函數/閉包賦值給一個常量還是變量第煮,您實際上都是將常量/變量的值設置為對應函數/閉包的引用。