参考书:《疯狂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}

引用类型

当闭包或函数被赋值给变量或常量时,变量或常量并没有用于保存闭包或函数,而是引用闭包或函数

因此, 当一个闭包或函数被赋值给多个变量或常量时,这些变量或常量都指向这个闭包或函数