参考书:《疯狂Swift讲义》李刚 编著
函数(Function)的设计是为了实现功能,闭包则是函数概念的扩展
捕获
拷贝所在封闭区域的常量和变量以供访问使用的行为称为捕获
函数与闭包
函数是具有名称,方便复用的代码块,闭包比函数更为灵活,类似与Objective-C的代码块和Java的Lambda表达式
函数是有名称的闭包:
全局函数:有名称,无捕获的闭包
嵌套函数:有名称,捕获封闭函数体值的闭包
闭包表达式:匿名称,捕获封闭函数体值的闭包
创建闭包
语法如下:
</pre><pre name="code" class="plain">{(形参列表)->返回值类型 in
执行语句
return语句
}
创建闭包与函数语法的区别:
①不使用fun关键字
②不使用名称
③返回值类型之后使用in关键字指明该代码块为闭包
④左花括号在形参列表之前
⑤不使用外部形参名
★笔者接触的是Swift最初的版本,该版本中定义闭包表达式时允许指定外部形参名,但是没有任何作用,或许在今后的版本中会改进
闭包类型
由于函数是特殊的闭包,因此函数的类型就是闭包的类型
简化表达式
闭包是灵活的代码块,因此 只要能够让Swift根据上下文推断闭包的类型,就可以部分地省略闭包表达式
①上下文推断:
当Swift能够根据上下文推断出形参类型时,此时形参类型和圆括号都可以省略
var square:(Int)->Int={val in return val*val}<strong>
</strong>
根据square的类型声明可以判断它是整型输入整型输出的闭包,因此不必指定val的类型和返回值的类型
var square={val in return val*val}(9)
根据闭包之后传入的参数9,以及return的表达式判断等号右边的闭包是整型输入整型输出的,此时square为接收闭包执行结果的变量,值为81
②省略return关键字:
执行体只有1行代码时可以省略return关键字
var cube={(val:Int)->Int in val*val*val}
③省略形参名和in关键字
执行体对形参名要求不高时,可以省略形参名和in关键字,通过临时变量依次代表形参列表中的每个形参
var pow:(Int)->Int={
<span style="white-space:pre"> </span>var result=1
<span style="white-space:pre"> </span>for i in 1...$1
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>result*=$0
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>return result
}
★
临时变量是从$0开始计数的
尾随闭包
闭包类型可以作为函数的参数类型和返回值类型
当函数的最后一个参数的类型是闭包类型时,Swift允许在函数调用时把闭包写在反圆括号之后,以提高程序的可读性
例如:
func involution(val:Int, f:(Int)->())
{
<span style="white-space:pre"> </span>return f(val)
}
var result=involution(10){$0*$0}
引用类型
当闭包或函数被赋值给变量或常量时,变量或常量并没有用于保存闭包或函数,而是引用闭包或函数
因此, 当一个闭包或函数被赋值给多个变量或常量时,这些变量或常量都指向这个闭包或函数