閉包表達(dá)式是一種利用簡(jiǎn)潔語(yǔ)法構(gòu)建內(nèi)聯(lián)閉包的方式德挣。 閉包表達(dá)式提供了一些語(yǔ)法優(yōu)化恭垦,使得撰寫閉包變得簡(jiǎn)單明了
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"]
上面是使用sorted函數(shù)對(duì)數(shù)組進(jìn)行字母逆序排序
閉包表達(dá)式版本代碼:
reversed = sorted(names, { (s1: String, s2: String) -> Bool in
return s1 > s2
})
閉包表達(dá)式語(yǔ)法有如下一般形式:
{ (parameters) -> returnType in
statements
}
因?yàn)榕判蜷]包函數(shù)是作為sorted函數(shù)的參數(shù)進(jìn)行傳入的,Swift可以推斷其參數(shù)和返回值的類型格嗅。 sorted期望第二個(gè)參數(shù)是類型為(String, String) -> Bool的函數(shù)番挺,因此實(shí)際上String,String和Bool類型并不需要作為閉包表達(dá)式定義中的一部分。 因?yàn)樗械念愋投伎梢员徽_推斷屯掖,返回箭頭 (->) 和圍繞在參數(shù)周圍的括號(hào)也可以被省略
reversed = sorted(names, { s1, s2 in return s1 > s2 } )
單行表達(dá)式閉包可以通過(guò)隱藏return關(guān)鍵字來(lái)隱式返回單行表達(dá)式的結(jié)果
reversed = sorted(names, { s1, s2 in s1 > s2 } )
Swift 自動(dòng)為內(nèi)聯(lián)函數(shù)提供了參數(shù)名稱縮寫功能玄柏,可以直接通過(guò)1,$2來(lái)順序調(diào)用閉包的參數(shù)。
reversed = sorted(names, { $0 > $1 } )
實(shí)際上還有一種更簡(jiǎn)短的方式, Swift 的String類型定義了關(guān)于大于號(hào) (>) 的字符串實(shí)現(xiàn)贴铜,其作為一個(gè)函數(shù)接受兩個(gè)String類型的參數(shù)并返回Bool類型的值粪摘。
reversed = sorted(names, >)
尾隨閉包
如果需要將一個(gè)很長(zhǎng)的閉包表達(dá)式作為最后一個(gè)參數(shù)傳遞給函數(shù),可以使用尾隨閉包來(lái)增強(qiáng)函數(shù)的可讀性绍坝。 尾隨閉包是一個(gè)書寫在函數(shù)括號(hào)之后的閉包表達(dá)式徘意,函數(shù)支持將其作為最后一個(gè)參數(shù)調(diào)用。
func someFunctionThatTakesAClosure(closure: () -> ()) {
// 函數(shù)體部分
}
// 以下是不使用尾隨閉包進(jìn)行函數(shù)調(diào)用
someFunctionThatTakesAClosure({
// 閉包主體部分
})
// 以下是使用尾隨閉包進(jìn)行函數(shù)調(diào)用
someFunctionThatTakesAClosure() {
// 閉包主體部分
}
上邊還可以寫成
reversed = sorted(names) { $0 > $1 }
例:使用尾隨閉包將Int類型數(shù)組[16,58,510]轉(zhuǎn)換為包含對(duì)應(yīng)String類型的數(shù)組["OneSix", "FiveEight", "FiveOneZero"]
Swift 的Array類型有一個(gè)map方法陷嘴,其獲取一個(gè)閉包表達(dá)式作為其唯一參數(shù)映砖。 數(shù)組中的每一個(gè)元素調(diào)用一次該閉包函數(shù),并返回該元素所映射的值(也可以是不同類型的值)灾挨。 具體的映射方式和返回值類型由閉包來(lái)指定邑退。
let digitNames = [
0: "Zero", 1: "One", 2: "Two", 3: "Three", 4: "Four",
5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"
]
let numbers = [16, 58, 510]
let strings = numbers.map {
(var number) -> String in
var output = ""
while number > 0 {
output = digitNames[number % 10]! + output
number /= 10
}
return output
}
// strings 常量被推斷為字符串類型數(shù)組竹宋,即 [String]
// 其值為 ["OneSix", "FiveEight", "FiveOneZero"]