閉包表達(dá)式語法有如下的一般形式:
{ (parameters) -> returnType in
statements
}
閉包表達(dá)式參數(shù) 可以是 in-out
參數(shù),但不能設(shè)定默認(rèn)值。也可以使用具名的可變參數(shù)(但是如果可變參數(shù)不放在參數(shù)列表的最后一位的話,調(diào)用閉包的時時編譯器將報錯。)
- 舉個例子
var names = ["Jack", "Bob", "Tom", "Alen", "James",]
var sortedArray = names.sorted(by: { (s1: String, s2: String) -> Bool in
return s1 > s2
})
閉包的函數(shù)體部分由關(guān)鍵字 in 引入。該關(guān)鍵字表示閉包的參數(shù)和返回值類型定義已經(jīng)完成,閉包函數(shù)體即將開始。
簡化之旅
根據(jù)上下文推斷類型
因為排序閉包函數(shù)是作為 sorted(by:) 方法的參數(shù)傳入的,Swift 可以推斷其參數(shù)和返回值的類型。 sorted(by:) 方法被一個字符串?dāng)?shù)組調(diào)用,因此其參數(shù)必須是 (String, String) -> Bool 類型的函數(shù)。這意味著 (String, String) 和 Bool 類型并不需要作為閉包表達(dá)式定義的一部分。因為所有的類型都可以被正確推斷,返回箭頭( -> )和圍繞在參數(shù)周圍的括號也可以被省略:
reversedNames = names.sorted(by: { s1, s2 in return s1 > s2 } )
單表達(dá)式閉包隱式返回
單行表達(dá)式閉包可以通過省略 return 關(guān)鍵字來隱式返回單行表達(dá)式的結(jié)果,如上版本的例子可以改寫為:
reversedNames = names.sorted(by: { s1, s2 in s1 > s2 } )
sorted(by:) 方法的參數(shù)類型明確了閉包必須返回一個 Bool 類型值。因為閉包函數(shù)體只包含了一個單一表達(dá)式( s1 > s2 ),該表達(dá)式返回 Bool 類型值,因此這里沒有歧義, return 關(guān)鍵字可以省略。
參數(shù)名稱縮寫
Swift 自動為內(nèi)聯(lián)閉包提供了參數(shù)名稱縮寫功能,你可以直接通過$0 , $1 , $2
來順序調(diào)用閉包的參數(shù),以此類推。
如果你在閉包表達(dá)式中使用參數(shù)名稱縮寫,你可以在閉包定義中省略參數(shù)列表,并且對應(yīng)參數(shù)名稱縮寫的類型會通過函數(shù)類型進(jìn)行推斷。in
關(guān)鍵字也同樣可以被省略,因為此時閉包表達(dá)式完全由閉包函數(shù)體構(gòu)成:
reversedNames = names.sorted(by: { $0 > $1 } )
在里的$0
和$1
表示閉包中第一個和第二個 String 類型的參數(shù)。運(yùn)算符方法
其實(shí)還有一種更簡短的方式來編寫上面例子中的閉包表達(dá)式。Swift 的String
類型定義了關(guān)于大于號(>)
的字符串實(shí)現(xiàn),其作為一個函數(shù)接受兩個String
類型的參數(shù)并返回Bool
類型的值。而這正好與
sorted(by:)
方法的參數(shù)需要的函數(shù)類型相符合。因此,你可以簡單地傳遞一個大于號,Swift 可以自動推斷出你想使用大于號的字符串函數(shù)實(shí)現(xiàn):
reversedNames = names.sorted(by: >)