什么是闭包?
闭包是词法闭包(Lexical Closure)的简称。是在其词法上下文中引用了自由变量(自由变量是指局部变量以为的变量)的函数。自由变量和函数一同存在。
另一种说法:闭包是有函数和其相关的引用环境组合而成的实体
在Swift中,闭包是自包含的函数代码块,可以捕获和存储器所在上下文中任意常量和变量的引用。
闭包的形式:
1.全局函数是一个有名字但不会捕获任何值的闭包
2.嵌套函数是一个有名字并可以其封闭函数作用域内的值的闭包
3.闭包表达式是一个利用轻量级语法所写的可以捕获器上下文中变量或常量值的匿名闭包
闭包的语法表达式
{ (paramenters) -> returnType in
statements
}
( paramenters ) 括号中为闭包的参数,可有可无; ->之后的为返回值类型 ;整个闭包用“in”关键字分隔开,in后为实现
typealias block = (Int) -> Void
闭包中可以使用常量,变量,和inout类型作为参数,但是不能提供默认值,元组也可以作为参数和返回值
根据上下文推断类型
举个例子:
var names = ["chris", "alex", "ewa", "barry", "daniella"]
可以看出,数组的排序方法sort中参数类型为两个参数为泛型返回一个bool值类型。按照正确的写法,我们可以这么写
names.sort({ (s1: String, s2: String) -> Bool in
return s1 > s2
})
上面代码中,我们明确指出了两个参数的数据类型和返回值类型
names.sort { (s1, s2) -> Bool in
return s1 > s2
}
上面代码可以看出,我们可以忽略参数的类型
names.sort { s1, s2 in
return s1 > s2
}
最后一种是最简洁的写法,忽略了参数的圆括号和类型,也省略了返回值类型,直接用in将参数和实现分隔开
实际上,在任何情况下,通过内联闭包表达式构造的闭包作为参数传递给函数时,在调用函数时都可以推断出闭包的参数值类型和返回值类型,这意味着我们几乎不需要利用完整格式构造任何内联闭包。
单表达式闭包隐式返回
names.sort { s1, s2 in s1 > s2 }
单行表达式闭包可以通过隐藏 return 关键字来隐式返回单行表达式的结果
尾随闭包(Trailing Closures)
如果需要一个很长的闭包表达式作为最后一个参数传递给函数,可以使用尾随闭包来增强函数的可读性
names.sort({ (s1: String, s2: String) -> Bool in
return s1 > s2
})
捕获值(Capturing Values)
闭包可以在其定义的上下文中捕获常量或变量。即使定义的这些常量和变量的原域已经不存在,闭包仍然可以在闭包函数体内引用和修改这些值。
嵌套函数是最简单的闭包形式。
闭包是引用类型
函数和闭包都是引用类型。将函数或者闭包赋值给一个常量或者变量,则该常量或者变量就是对应函数或闭包的引用,指向对应的闭包和函数。
func add(a: Int, b: Int) -> Int {
return a + b
}
let afunc = add
afunc指向add函数。
注:引用《The Swift Programming Language》
发现有不对的地方欢迎指正