https://developer.apple.com/library/prerelease/content/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html#//apple_ref/doc/uid/TP40014097-CH11-ID94
闭包是个代码块, 跟函数很像, 是Swift特有的一个语法。 苹果介绍了它的概念,包含3种形式:
1、全局函数是个有名称的闭包, 不使用任何作用域内的参数;
2、嵌套函数是个有名称的闭包,可以使用外边全局函数的局部变量;
3、匿名表达式即没有函数名称,并可以读取作用域内的变量;
4、闭包内使用self参数时,为了避免相互引用导致内存不回收问题, 要添加 [unowned self] 前缀。
以String的sorted方法为例, 说明闭包的用法(有点像Java的Comparator)
let students = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
func forward(_ s1: String, _ s2: String) -> Bool {
return s1 < s2
}
var reversedNames = students.sorted(by: forward)
for tmp1 in reversedNames {
print(tmp1)
}
上边代码式按照从低到高排序, 输出:
Alex
Barry
Chris
Daniella
Ewa
闭包表达式的基本定义:
-
{ (parameters) -> return type in
-
statements
-
}
如果闭包里使用self参数, 为了避免相互引用。 要使用 unowned self , 例如:
{ [unowned self] (params) -> return type in
代码
self.....
}
包含参数、返回值、关键字in、代码块、返回值和大括号, 其中代码大括号和代码是必须的、其它是可省略的。
按照上述定义, 重新写sorted方法如下(功能不变):
var reversedNames = students.sorted(by: {(s1: String, s2: String) -> Bool in
return s1 < s2
})
因为Swift可以通过参数值确定参数类型, 所以可以省略参数类型, 即
var reversedNames = students.sorted(by: {(s1, s2) -> Bool in
return s1 < s2
})
Swift语言的设计原则是能省则省, 因为闭包表达式总是需要一个返回值。 如果代码块只有一句代码,那么可以省略return关键字。(说明:必须是只有一行代码,才能省略return关键字)
var reversedNames = students.sorted(by: {(s1, s2) -> Bool in
s1 < s2
})
因为String的sorted方法的参数肯定是(String, String)->Bool类型(有点像C语言的函数指针), 可以省略这些参数。
public func sorted(by areInIncreasingOrder: (Element, Element) -> Bool) -> [Element]
var reversedNames = students.sorted(by: {s1, s2 in
s1 < s2
})
Swift闭包参数可以是$0,$1,$2......,表示第1个、第2个、第3个等等参数, 即$0可以替换s1、$1可以替换s2。
var reversedNames = students.sorted(by: {
$0 < $1
})
对于String数组排序, sorted方法就是需要判断大小的true或false, 还可以写成
var reversedNames = students.sorted(by: <)
这个写法就很高大上了, 简洁的不能再简洁了。
闭包还可以定义函数: