我们从一个Swift函数说起。并以此为例子。
Swift的标准库提供了一个叫做sorted(by:)的方法,会根据你提供的排序闭包将已知类型的数组的值进行排序。一旦它排序完成,sorted(by:)方法会返回与原数组类型大小完全相同的一个新数组,该数组的元素是已排序好的。原始数组不会被sorted(by:)方法修改。
我们以soted方法为例子,对一个数组进行排序,查看各种闭包表达到最后尾随闭包
//使用函数表达式作为参数,对数组进行排序
let numArr = [5, 4, 6, 1, 7]
//构建排序逻辑,作为闭包传入sorted方法
func backward(num1 : Int, num2: Int) -> Bool {
return num1 > num2
}
var reversedNumArr = numArr.sorted(by: backward)
print(reversedNumArr) //输出:[7, 6, 5, 4, 1]
闭包表达式语法能够使用常量形式参数、变量形式参数和输入输出形式参数,但不能提供默认值。可变形式参数也能使用,但需要在形式参数列表的最后面使用。元组也可被用来作为形式参数和返回类型。
我们使用闭包来代替backward函数,直接写一个符合sorted函数要求的闭包
//使用闭包表达式,对数组进行排序
let numArr = [5, 4, 6, 1, 7]
//构建一个入参为两个int类型,返回一个bool的闭包表达式,使用{}括起来
var reversedNumArr = numArr.sorted(by: {(num1: Int, num2: Int) -> Bool in
return num1 > num2
})
print(reversedNumArr) //输出:[7, 6, 5, 4, 1]
因排序闭包为实际参数来传递给函数,Swift能推断它的形式参数类型和返回类型(根据我们数组的类型,swift可以判断我们闭包需要的参数类型)
在numArr数组使用sorted时,sorted(by:)方法期望它的形式参数是一个(Int,Int)->Bool类型的函数。这意昧着(Int,Int)参数类型和Bool返回类型不需要被写成闭包表达式定义中的一部分,因为所有的类型都能被推断,返回箭头(->)和围绕在形式参数名周围的括号也能被省略
let numArr = [5, 4, 6, 1, 7]
var reversedNumArr = numArr.sorted(by: {(num1, num2) in
return num1 > num2
})
print(reversedNumArr) //输出:[7, 6, 5, 4, 1]
单表达式(浅显理解就只有一行代码,一个完整的表达)的函数或者闭包,我们可以将reture去掉。此叫做单表达式隐式返回
//使用闭包表达式,对数组进行排序
let numArr = [5, 4, 6, 1, 7]
var reversedNumArr = numArr.sorted(by: {num1, num2 in num1 > num2})
print(reversedNumArr) //输出:[7, 6, 5, 4, 1]
swift自动对行内闭包提供简写实际参数名,使用$0,$1,$2此中类型来替代。也就是说我们可以不用专门声明num1和num2这种形参,可以直接使用$0和$2来取代num1和num2。所以既然闭包内可以使用$0和$1这种实际参数直接访问numArr的参数,我们也不必在闭包中声明(num1: Int, num2: Int)这中形式参数,然后我们的闭包表达式还可以再简写
//使用闭包表达式,对数组进行排序
let numArr = [5, 4, 6, 1, 7]
var reversedNumArr = numArr.sorted(by: {$0 > $1})
print(reversedNumArr) //输出:[7, 6, 5, 4, 1]
Swift的Int、float等还有String类型定义了关于大于号(>)的特定字符串实现,让其作为一个有两个相对应类型形式参数的函数并返回一个Bool类型的值。这正好与sorted(by:)方法的形式参数需要的函数相匹配。因此,你能简单地传递一个大于号,并且Swift将推断你想使用大于号特殊字符串函数实现
//使用闭包表达式,对数组进行排序
let numArr = [5, 4, 6, 1, 7]
var reversedNumArr = numArr.sorted(by: > )
print(reversedNumArr) //输出:[7, 6, 5, 4, 1]
最后来到了我们的尾随闭包
如果你需要将一个很长的闭包表达式作为函数最后一个实际参数传递给函数,使用尾随闭包将增强函数的可读性。尾随闭包是一个被书写在函数形式参数的括号外面(后面)的闭包表达式。
//使用闭包表达式,对数组进行排序
let numArr = [5, 4, 6, 1, 7]
var reversedNumArr = numArr.sorted{$0 > $1}
print(reversedNumArr) //输出:[7, 6, 5, 4, 1]
//自此我们排序从此变为最后的尾随闭包,更加简洁易读
let numArr = [5, 4, 6, 1, 7]
//构建排序逻辑,作为闭包传入sorted方法
func backward(num1 : Int, num2: Int) -> Bool {
return num1 > num2
}
var reversedNumArr = numArr.sorted(by: backward)
print(reversedNumArr) //输出:[7, 6, 5, 4, 1]
//使用尾随闭包
let numArr = [5, 4, 6, 1, 7]
var reversedNumArr = numArr.sorted{$0 > $1}
print(reversedNumArr) //输出:[7, 6, 5, 4, 1]