闭包表达式语法
{ (parameters) -> returnType in
statements
}
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
names.sort({ (s1: String, s2: String) -> Bool in
return s1 > s2
})
根据上下文推断
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
names.sort({ s1,s2 in
return s1 > s2
})
单表达式闭包隐式返回
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
names.sort({ s1,s2 in s1 > s2
})
参数名简写
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
names.sort({ $0 > $1
})
运算符函数
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
names.sort(>)
尾随闭包
如果您需要将一个很长的闭包表达式作为最后一个参数传递给函数,可以使用尾随闭包来增强函数的可读性。
尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用。
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
names.sort(){$0 > $1}
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 常量被推断为字符串类型数组,即 [String]
// 其值为 ["OneSix", "FiveEight", "FiveOneZero"]
值捕获
func makeIncrementor(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0
func incrementor() -> Int {
runningTotal += amount
return runningTotal
}
return incrementor
}
let incrementByTen = makeIncrementor(forIncrement: 10)
incrementByTen()
// 返回的值为10
incrementByTen()
// 返回的值为20
incrementByTen()
// 返回的值为30
下面的例子中,incrementBySevne捕获了一个新的runningTotal变量,该变量和incrementByTen中捕获的变量没有任何联系:
let incrementBySeven = makeIncrementor(forIncrement: 7)
incrementBySeven()
// 返回的值为7
incrementByTen()
// 返回的值为40
闭包是引用类型
上面的例子中,incrementBySeven和incrementByTen是常量,但是这些常量指向的闭包仍然可以增加其捕获的变量值。 这是因为函数和闭包都是引用类型。
无论您将函数/闭包赋值给一个常量还是变量,您实际上都是将常量/变量的值设置为对应函数/闭包的引用。
无论您将函数/闭包赋值给一个常量还是变量,您实际上都是将常量/变量的值设置为对应函数/闭包的引用。
上面的例子中,incrementByTen指向闭包的引用是一个常量,而并非闭包内容本身。
这也意味着如果您将闭包赋值给了两个不同的常量/变量,两个值都会指向同一个闭包:
这也意味着如果您将闭包赋值给了两个不同的常量/变量,两个值都会指向同一个闭包:
let alsoIncrementByTen = incrementByTen
alsoIncrementByTen()
// 返回的值为50