1、什么是闭包
闭包简单的来说就是匿名函数、lambdas函数 ,书面点的来说就是闭包是自包含的函数代码块,可以在代码中被传递和使用,可以捕获和存储其所在上下文中任意常量和变量的引用。 这就是所谓的闭合并包裹着这些常量和变量,俗称闭包。
2、闭包采取的形式
前面在函数文章中,都定义的是全局函数,以及内嵌函数 实际上都是闭包的一种特殊形式。
闭包表达式是一种利用简洁语法构建内联闭包的方式。它提供了一些语法优化,使得撰写闭包变得简单明了。下面来分析下它怎么简单明了。
5、示例:sorted函数(Swift 标准库提供了sorted
函数,会根据您提供的基于输出类型排序的闭包函数将已知类型数组中的值进行排序。 一旦排序完成,函数会返回一个与原数组大小相同的新数组,该数组中包含已经正确排序的同类型元素。)
let names = ["Chris","Alex","Ewa","Barry","Daniella"]
func backwards(s1: String,s2: String) -> Bool { return s1 > s2 } var reversed = sorted(names,backwards) // reversed 为 ["Ewa","Daniella","Chris","Alex"]
sorted
函数需要传入两个参数:
- 已知类型的数组
- 闭包函数,该闭包函数需要传入与数组类型相同的两个值,并返回一个布尔类型值来告诉
sorted
函数当排序结束后传入的第一个参数排在第二个参数前面还是后面。如果第一个参数值出现在第二个参数值前面,排序闭包函数需要返回true
,反之返回false
。
{ (parameters) -> returnType in statements }
那上面的调用方法可以优化成什么样子呢。
reversed = sorted(names,{ (s1: String,s2: String) -> Bool in return s1 > s2 })
in 关键字,他表示参数和返回值定义完成,函数体即将开始。
swift是一个参数类型确定的语言,它也能够推断参数类型。所以这里还可以这样写。
reversed = sorted(names,{ s1,s2 in return s1 > s2 } )
对于单表达式闭包,还可以隐藏return关键字。
reversed = sorted(names,s2 in s1 > s2 } )
Swift 自动为内联函数提供了参数名称缩写功能,您可以直接通过
$0
,$1
$2来顺序调用闭包的参数。
reversed = sorted(names,{ $0 > $1 } )
还可以是用运算符函数
reversed = sorted(names,>)
不过说了这么多。可读性就被完全抹杀了。。。
那如果需要在闭包中输入很长的函数体,那就麻烦了。读起来不方便,所以就有了尾随闭包。闭包放在函数尾巴上。
那上面可以写成:
reversed = sorted(names) { $0 > $1 }
6、值捕获
闭包可以在其定义的上下文中捕获常量或变量。 即使定义这些常量和变量的原域已经不存在,闭包仍然可以在闭包函数体内引用和修改这些值。
func makeIncrementor(forIncrement amount: Int) -> () -> Int { var runningTotal = 0 func incrementor() -> Int { runningTotal += amount return runningTotal } return incrementor }
通过前面的接触,上面这个函数看懂了么。。。
这个函数接收一个叫forIncrement的外部参数名的Int参数,并返回一个()->Int 的函数类型。
在内嵌函数中没有接收runningTotal这个参数也能使用,就是内嵌函数捕获了包含它的函数体内的变量
闭包是引用类型