閉包是自包含的函數(shù)代碼塊漱挎,可以在代碼中被傳遞和使用。
Swift 中的閉包與 C 和 Objective-C 中的代碼塊(blocks)以及其他一些編程語言中的匿名函數(shù)比較相似雀哨。
閉包可以捕獲和存儲其所在上下文中任意常量和變量的引用磕谅。
1 閉包表達式(Closure Expressions)
// sorted 方法(The Sorted Method)
// 原數(shù)組不會被 sorted(by:) 方法修改私爷。
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella", "Andy", "Amni"]
func backward(_ s1: String, _ s2: String) -> Bool {
return s1 > s2
}
var reversedNames = names.sorted(by: backward)
閉包表達式語法:
{ (parameters) -> returnType in
statements
}
關(guān)鍵字`in`表示閉包的參數(shù)和返回值類型定義已經(jīng)完成,閉包函數(shù)體即將開始膊夹。
var reversedNames2 = names.sorted(by: {(s1:String, s2:String) -> Bool in return s1>s2})
根據(jù)上下文推斷類型(Inferring Type From Context)
var reversedNames3 = names.sorted(by: {(s1, s2)->Bool in return s1>s2})
根據(jù)上下文推斷類型(Inferring Type From Context) 省略 return 和 返回值
var reversedNames4 = names.sorted(by: {(s1, s2) in s1>s2})
參數(shù)名稱縮寫(Shorthand Argument Names):直接通過 1 硅确, $2 來順序調(diào)用閉包的參數(shù)
var reversedNames5 = names.sorted(by: {$0>$1})
運算符方法(Operator Methods)
var reversedNames6 = names.sorted(by: >)
2 尾隨閉包(Trailing Closures):將一個很長的閉包表達式作為最后一個參數(shù)傳遞給函數(shù)
不使用尾隨閉包進行函數(shù)調(diào)用:
func someFunctionThatTakesAClosure(closure: {
// 閉包主體部分
})
使用尾隨閉包進行函數(shù)調(diào)用:
func someFunctionThatTakesAClosure() {
// 閉包主體部分
}
var reversedNames7 = names.sorted(){$0>$1}
var reversedNames8 = names.sorted{$0>$1} // 當閉包表達式是唯一參數(shù)時役纹, ()可省略
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 {
(number) -> String in
var number = number
var output = ""
repeat {
output = digitNames[number%10]! + output // 字典下標返回一個可選值(optional value)
number /= 10
} while number > 0
return output
}
3 值捕獲(Capturing Values)
閉包可以在其被定義的上下文中捕獲常量或變量。即使定義這些常量和變量的原作用域已經(jīng)不存在迈套,閉包仍然可以在閉包函數(shù)體內(nèi)引用和修改這些值宏榕。
嵌套函數(shù) 是 捕獲值的閉包的最簡單形式
func makeIncrementer(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0
func incrementer() -> Int {
runningTotal += amount
return runningTotal
}
return incrementer
}
var funcby10 = makeIncrementer(forIncrement: 10)
var funcby50 = makeIncrementer(forIncrement: 50)
// 新生成的incrementer函數(shù)拓诸,都會各自獲得類似全局變量的 amount和runingTotal
funcby50()
funcby50()
funcby10()
4 閉包是引用類型(Closures Are Reference Types)
// 函數(shù)和閉包都是引用類型
// 無論將函數(shù)或閉包賦值給一個常量還是變量,實際上都是將常量或變量的值設(shè)置為對應(yīng)函數(shù)或閉包的引用麻昼。
let funcbyTen = funcby10
funcbyTen()
逃逸閉包(Escaping Closures)
自動閉包(Autoclosures)
playground文件在andyRon/LearnSwift