闭包是自包含的函数代码块,可以在代码中传递和使用。闭包可以捕获和存储其所在的上下文中任意常量和变量的引用。
闭包表达式
{ (parameters) -> returnType in
statements
}
闭包表达式语法可以使用常量、变量和inout类型作为参数,不能提供默认值。
let names = ["Chris","Alex","Ewa","Barry","Daniel"];
func backwards(s1:String, _ s2:String) ->Bool{
return s1>s2
}
let reversed = names.sort(backwards);
这个对应得闭包写法是:
let reversed = names.sort({(s1:String, s2:String) -> Bool in
return s1>s2})
①参数和返回类型可自动推断
因为排序闭包函数是作为sort(_:)方法的参数传入的,Swift 可以推断其参数和返回值的类型。
let reversed = names.sort({(s1, s2) in
return s1>s2})
②单表达式可以忽略return关键词
let reversed = names.sort({(s1, s2) in
s1>s2})
③可使用快捷参数,前缀$+数字,从0开始递增
let reversed = names.sort({ $0>$1})
尾随闭包
尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用:
let reversed = names.sort(){ $0>$1}
捕获值
闭包可以在其被定义的上下文中捕获常量或变量。即使定义这些常量和变量的原作用域已经不存在,闭包仍然可以在闭包函数体内引用和修改这些值。
嵌套函数
func makeIncrementer(forIncrement amount:Int) -> () ->Int{
var runningTotal = 0
func increment() -> Int{ //increment 这个函数没有参数
runningTotal += amount
return runningTotal
}
return increment
}
let amot = makeIncrementer(forIncrement: 5)
//amot =()->Int
amot() //5
单从函数来看increment函数没有任何参数,但是其函数体被引用了runningTotal和amount。这是因为它从外围函数捕获了runningTotal和amount变量的引用。捕获引用保证了runningTotal和amount变量在调用完makeIncrementer后不会消失,并且保证了在下一次执行incrementer函数时,runningTotal依旧存在。
func makeIncrementer1(forIncrement amount:Int) -> ()->Int{
var runningTotal = 0;
let increment = {()->Int in
runningTotal += amount;
return runningTotal
}
return increment
}