闭包(Closusures)
闭包是自包含的函数代码块,可以在代码中被传递和使用。swift中的必败与C和OC中的代码块(block)比较相似
闭包可以捕获和存储起所在上下文中任意常量和变量的引用,这就是所谓的闭合并包裹着这些常量和比昂两,俗称闭包。
函数章节介绍的全局和嵌套函数实际上也是特殊的闭包,闭包采取如下三种形式之一:
- 1.全局函数是一个有名字但不会捕获任何值得闭包
- 2.嵌套函数是一个有名字并可以捕获起封闭函数域内值得闭包
- 3.闭包表达式是一个利用轻量级语法所写的可以捕获其上下文中变量或常量值得匿名闭包
swift闭包在常见场景中进行语法优化,主要优化如下:
- 利用上下文推断参数和返回值类型
- 隐式返回单表达式闭包,即单表达式闭包可以省略return关键字
- 参数名称缩写
- 尾随闭包语法
闭包表达式
- 闭包表达式是一种利用简洁语法构建内联闭包的方式
- 例子:闭包表达示例使用sort函数对一个String类型的数组进行字母逆序排序
let names = ["Joke", "Rose", "James", "Kobe", "Paul"]
sort函数需要传入两个参数:1.一只类型的数组 2.闭包函数,闭包函数需要传入与数组类型相同的两个值,兵返回一个布尔类型值来告诉sorted函数正序还是逆序
func backwards(_ s1: String, s2: String) -> Bool {
return s1 > s2
}
闭包表达式的语法有如下一般形式
- 闭包表达式语法可以使用常量、变量和inout类型作为参数,不提供默认值,也可以在参数列表的最后使用可变参数,元组也可以作为参数和返回值
{ (parameters) -> returnType in
statements
}
var reversed = names.sorted(by: {(s1: String, s2: String) -> Bool in return s1 > s2})
print(reversed);
//["Rose", "Paul", "Kobe", "Joke", "James"]
根据上下文类型推断
- 因为排序闭包是作为sort函数的参数进行传入的,swift可以推断其参数和返回值的类型。sort期望第参数的类型是(String, String) -> Bool的函数。实际上任何情况下,通过内联闭包表达式构造的闭包作为参数传递给函数时,都可以推断出闭包的参数和返回值类型,这意味着您几乎不需要利用完整构造任何内联闭包
reversed = names.sorted(by: {s1, s2 in return s1 > s2})
print(reversed)
//["Rose", "Paul", "Kobe", "Joke", "James"]
单表达式闭包隐式返回
- 单行表达式闭包可以通过隐藏return关键字来隐式返回单行表达式的结果
reversed = names.sorted(by: {s1, s2 in s1 > s2})
print(reversed)
//["Rose", "Paul", "Kobe", "Joke", "James"]
参数名称缩写
- swift自动为内联函数提供了参数名称缩写功能,可以通过$0,$1,$2来顺序调用闭包的参数。
reversed = names.sorted(by: {$0 > $1})
print(reversed)
//["Rose", "Paul", "Kobe", "Joke", "James"]
运算符函数
reversed = names.sorted(by: >)
print(reversed)
//["Rose", "Paul", "Kobe", "Joke", "James"]
尾随闭包
如果需要将一个很长的闭包表达式作为最后一个参数传递给函数,可以使用尾随闭包来增强函数的可读性。尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用
func someFunctionThatTakesAClosure(_ closure:() -> ()) {
//函数体部分
}
不使用尾随闭包进行函数调用
someFunctionThatTakesAClosure({
//闭包主体部分
})
使用尾随闭包进行函数调用
someFunctionThatTakesAClosure(){
//闭包主体部分
}
reversed = names.sorted() {
$0 > $1
}
网友评论