一. 闭包表达式(Closure Expression)
在Swift中,可以通过func定义一个函数,也可以通过闭包表达式定义一个函数,闭包表达式和闭包是两回事
闭包表达式的格式如下:
{
(参数列表) -> 返回值类型 in
函数体代码
}
通过func定义一个函数:
func sum(_ v1: Int, _ v2: Int) -> Int { v1 + v2 }
通过闭包表达式定义一个函数:
//通过闭包表达式定义一个函数,然后调用
var fn = {
(v1: Int, v2: Int) -> Int in
return v1 + v2
}
fn(10, 20) //闭包调用的时候默认不用写参数名称的
//通过闭包表达式定义一个函数,并且直接调用
{
(v1: Int, v2: Int) -> Int in
return v1 + v2
}(10, 20)
二. 闭包表达式的简写
//传入两个Int变量,返回一个函数
func exec(v1: Int, v2: Int, fn: (Int, Int) -> Int) {
print(fn(v1, v2))
}
//什么都不省略
exec(v1: 10, v2: 20, fn: {
(v1: Int, v2: Int) -> Int in
return v1 + v2
})
//省略参数类型、返回值类型 (因为编译器能推断出来)
exec(v1: 10, v2: 20, fn: {
v1, v2 in return v1 + v2
})
//省略return
exec(v1: 10, v2: 20, fn: {
v1, v2 in v1 + v2
})
//超级简写:$0代表第一个参数,$1代表第二个参数
exec(v1: 10, v2: 20, fn: { $0 + $1 })
//终极简写:只用一个+
exec(v1: 10, v2: 20, fn: +)
三. 尾随闭包
如果将一个很长的闭包表达式作为函数的最后一个实参,使用尾随闭包可以增强函数的可读性。
尾随闭包是一个被书写在函数调用括号外面(后面)的闭包表达式。
func exec(v1: Int, v2: Int, fn: (Int, Int) -> Int) {
print(fn(v1, v2))
}
//写成尾随闭包,增强函数的可读性
exec(v1: 10, v2: 20) {
$0 + $1
}
如果闭包表达式是函数的唯一实参,而且使用了尾随闭包的语法,那就不需要在函数名后边写圆括号(因为没其他参数了,肯定可以省略圆括号)
func exec(fn: (Int, Int) -> Int) {
print(fn(1, 2))
}
exec(fn: { $0 + $1 }) //都不省略
exec() { $0 + $1 } //省略标签
exec { $0 + $1 } //省略标签和()
忽略参数
func exec(fn: (Int, Int) -> Int) {
print(fn(1, 2))
}
//用_忽略参数
exec { _,_ in 10 } //10
示例:数组的排序
sort函数要求传入一个(Element, Element) -> Bool类型的参数:
func sort(by areInIncreasingOrder: (Element, Element) -> Bool)
可以传入函数:
// 返回true: i1排在i2前面,返回false: i1排在i2后面
func cmp(i1: Int, i2: Int) -> Bool {
// 大的排在前面
return i1 > i2
}
var nums = [11, 2, 18, 6, 5, 68,