swift中的闭包与OC 中的block差不多是一个概念,只是语法格式不一样,但作用是一样的。主要是用于callBack(异步回调)或者两个类之间的通信。它的本质一个函数,一个可执行的代码块,只是这个函数是没有名字的,也就是匿名函数。你也可以把他看作如 int、float一样,是一种数据类型,一种可以作为参数传递的数据类型。
闭包表达式拥有简洁的风格,swift鼓励开发者再常见的场景中进行语法优化,主要优化:
- 利用上下文推断参数和返回值类型
- 从单行表达式闭包中隐式返回(也就是闭包体只有一行代码,可以省略return)
- 可以使用简化参数名,如1(从0开始,表示第i个参数...)
- 提供了尾随闭包语法(Trailing closure syntax)
闭包表达式是:()-> () 记住这样的形式就好了,这是最简单的闭包表达式。意思是没有参数没有返回值的一个闭包
以下定义了一个接收参数并返回指定类型的闭包语法:
{(paramaters) -> (return type) in
...
}
举个官方文档中的:数组的sorted(by:) 方法
//如果使用普通函数进行排序:
func backwards(s1: String, s2: String) -> Bool {
return s1 > s2
}
names.sorted(by: <#T##(String, String) throws -> Bool#>)
func backwards(s1: String, s2: String) -> Bool {
return s1 > s2
}
var reversed = names.sorted(by: backwards)
print(reversed)//["Ella", "Celina", "Banana", "Ala"]
sort函数是将一个已知类型数组中的值进行排序的方法。排序完成,函数会返回一个与原数组只有顺序不同的新数组。
)
现在我们来看如何做到第一种优化:利用上下文推断参数和返回值类型
可以看到 sort:by方法的两个参数和返回值,
下面可以的表达和上面的是一样的:
var reversed = names.sorted { (s1:String, s2:String) -> Bool in
return s1 > s2
}
需要注意的是行内闭包的形式参数类型和返回类型的声明与 backwards(::) 函数的申明相同。在这两个方式中,都书写成 (s1: String, s2: String) -> Bool。总之对于行内闭包表达式来说,形式参数类型和返回类型都应写在花括号内而不是花括号外面。
从语境中推断类型
因排序闭包为实际参数来传递给函数,故 Swift 能推断它的形式参数类型和返回类型。 sorted(by:) 方法期望它的第二个形式参数是一个 (String, String) -> Bool 类型的函数。这意味着 (String, String)和 Bool 类型不需要被写成闭包表达式定义中的一部分,因为所有的类型都能被推断,返回箭头 ( ->) 和围绕在形式参数名周围的括号也能被省略:
var reversed = names.sorted { (s1, s2) in return s1 > s2 }
是不是很逆天!
还有更逆天的!!
从单表达式闭包隐式返回
单表达式闭包能够通过从它们的声明中删掉 return 关键字来隐式返回它们单个表达式的结果,前面的还可以这样:
var reversed = names.sorted { (s1, s2) in s1 > s2}
缩写参数名
swift 提供了参数名缩写的功能,直接可以用1,$2(0是第一个参数),参数名称的类型也会进行类型推断,此时in也被省略掉了,是不是吊炸天了! 但是这样写可读性太差了,不建议这样写。
var reversed = names.sorted { ($0 > $1)}