最近在学习RxSwift>>>,大量接触闭包的使用,趁着下班前,翻译了Swift官方文档中闭包那常常使用的一部分,看成复习。git
Closure表达式语法具备如下通常形式:github
{ (parameters) -> return type in
statements
}
复制代码
闭包表达式语法中的参数能够是输入参数,但它们不能有默认值。若是命名可变参数,可使用变量参数。元组也能够用做参数类型和返回类型。数组
看一个例子:将一个数组排序。以前的作法是:定义一个方法,传入数组,返回排序结果。bash
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
func backward(_ s1: String, _ s2: String) -> Bool {
return s1 > s2
}
var reversedNames = names.sorted(by: backward)
复制代码
使用闭包之后:闭包
reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in
return s1 > s2
})
复制代码
因为闭包的体积很是短,因此它甚至能够写在一行上:函数
reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in return s1 > s2 } )
复制代码
从上下文推断类型学习
由于排序闭包做为参数传递给方法,因此Swift能够推断它的参数类型和它返回的值的类型。排序后的(by :)方法在字符串数组上调用,因此它的参数必须是类型(String,String) - > Bool的函数。这意味着(String,String)和Bool类型不须要做为闭包表达式定义的一部分写入。因为能够推断全部类型,所以也能够省略返回箭头( - >)和参数名称周围的括号:ui
reversedNames = names.sorted(by: { s1, s2 in return s1 > s2 } )
复制代码
在将闭包做为内联闭包表达式传递给函数或方法时,始终能够推断参数类型和返回类型。所以,当闭包用做函数或方法参数时,您毫不须要以最充分的形式编写内联闭包。this
来自单表达式闭包的隐式返回spa
经过在声明中省略return关键字,单表达式闭包可隐式返回其单个表达式的结果,如前面示例的此版本所示:
reversedNames = names.sorted(by: { s1, s2 in s1 > s2 } )
复制代码
这里,排序后的(by :)方法参数的函数类型清楚地代表了闭包必须返回一个Bool值。因为闭包的主体包含一个返回Bool值的单个表达式(s1> s2),所以不存在歧义,而且能够省略return关键字。
速记参数名称
Swift自动为内联闭包提供速记参数名称,这些名称可用于经过名称 1,$ 2等引用闭包参数的值。
reversedNames = names.sorted(by: { $0 > $1 } )
复制代码
若是须要将闭包表达式做为函数的最终参数传递给函数,而且闭包表达式很长,那么将其做为尾部闭包编写可能会颇有用。尾随闭包在函数调用的括号后面写入,尽管它仍然是该函数的参数。在使用尾随闭包语法时,不要将闭包的参数标签做为函数调用的一部分写入。
func someFunctionThatTakesAClosure(closure: () -> Void) {
// function body goes here
}
// Here's how you call this function without using a trailing closure: someFunctionThatTakesAClosure(closure: { // closure's body goes here
})
// Here's how you call this function with a trailing closure instead: someFunctionThatTakesAClosure() { // trailing closure's body goes here
}
复制代码
上面的Closure Expression Syntax部分中的字符串排序闭包能够在排序的(by :)方法的括号以外写为尾部闭包:
reversedNames = names.sorted() { $0 > $1 }
复制代码
若是提供闭包表达式做为函数或方法的惟一参数,而且将该表达式做为尾随闭包提供,则在调用该函数时,无需在函数或方法名称后面编写一对括号():
reversedNames = names.sorted { $0 > $1 }
复制代码
当封闭足够长以致于不可能将它写在一行上时,尾随封闭很是有用。做为一个例子,Swift的数组类型有一个map(_ :)方法,它将一个闭包表达式做为其单个参数。对于数组中的每一个项目都调用一次闭包,并为该项目返回一个替代映射值(多是某种其余类型)。映射的性质和返回值的类型留给闭包来指定。