Swift闭包函数(Array)
2016-03-16 本文已影响207人
Mi欧阳
闭包概述:(以下是我拷贝的)
闭包(Closures)
- 闭包是自包含的功能代码块,可以在代码中使用或者用来作为参数传值。
- 在Swift中的闭包与C、OC中的blocks和其它编程语言(如Python)中的lambdas类似。
- 闭包可以捕获和存储上下文中定义的的任何常量和变量的引用。这就是所谓的变量和变量的自封闭,
- 因此命名为”闭包“("Closures)").Swift还会处理所有捕获的引用的内存管理。
- 全局函数和嵌套函数其实就是特殊的闭包。
- 闭包的形式有:
- (1)全局函数都是闭包,有名字但不能捕获任何值。
- (2)嵌套函数都是闭包,且有名字,也能捕获封闭函数内的值。
- (3)闭包表达式都是无名闭包,使用轻量级语法,可以根据上下文环境捕获值。
- Swift中的闭包有很多优化的地方:
- (1)根据上下文推断参数和返回值类型
- (2)从单行表达式闭包中隐式返回(也就是闭包体只有一行代码,可以省略return)
- (3)可以使用简化参数名,如$0, $1(从0开始,表示第i个参数...)
- (4)提供了尾随闭包语法(Trailing closure syntax)
问题:对names中的元素按字母升序排序 (Z最小,A最大)
var names = ["Swift", "Arial", "Soga", "Donary"]
函数写法
func backwards(s1: String, s2: String) -> Bool {
return s1 > s2 // 升序排序
}
var reversed = names.sort(backwards)
把上面的普通函数写法转换为闭包函数
reversed = names.sort({
(s1: String, s2: String) -> Bool in
return s1 > s2
})
sort是一个排序函数,它通过基于输出类型排序的闭包函数,给已知类型的数组数据的值排序。需要一个闭包参数作为参数:Sort函数的完整抽象形态如下:
names.sort { (String1, String2) -> Bool in
do someting
return Bool
}
sort也是一个尾随闭包函数(Trailing Closures)
如果函数需要一个闭包参数作为参数,且这个参数是最后一个参数,而这个闭包表达式又很长时,可以使用尾随闭包。尾随闭包可以放在函数参数列表外,也就是括号外。
如果尾随闭包函数只有一个参数,那么可以把括号()省略掉,后面直接跟着闭包。
尾随闭包去掉括号
reversed = names.sort{
(s1: String, s2: String) -> Bool in
return s1 > s2
}
由于参数传入时swift会进行隐式类型推导,省去参数类型
reversed = names.sort{
(s1,s2) -> Bool in
return s1 > s2
}
同理由于结果return时swift会进行隐式类型推导,省去返回值类型
reversed = names.sort{
(s1,s2) in
return s1 > s2
}
既然类型都没了,闭包里面自带了一套默认的参数名,你可以不声明闭包参数列表。
第一参数:$0,第二参数:$1 ...
这是后闭包函数声明中的参数列表和返回值类型都没了
那么关键字in也省了吧,直接写内部结构体
reversed = names.sort{
return $0 > $1
}
如果内部结构体中只有return这么一句话,return也能省
reversed = names.sort{$0 > $1}
最简单的写法,只留下操作符,注意,这时候尾闭包使用的是()
这种方法只适用于闭包中只有"默认参数名"和"运算符"这两者的情况
reversed = names.sort(>)
闭包的运用:捕获值(内嵌函数捕获外部函数中定义的常量和变量)
func increment(amount amount: Int) -> (() -> Int) {
var total = 0
func incrementAmount() -> Int {
total += amount // total是外部函数体内的变量,这里是可以捕获到的
return total
}
return incrementAmount // 返回的是一个嵌套函数(闭包)
}
// 闭包是引用类型,所以incrementByTen声明为常量也可以修改total
let incrementByTen = increment(amount: 10)
incrementByTen() // return 10,incrementByTen是一个闭包
incrementByTen() // return 20
incrementByTen() // return 30
let incrementByOne = increment(amount: 1)
incrementByOne() // return 1
incrementByOne() // return 2
incrementByOne() // return 3
//函数本身不占内存,使用赋值后才占.
//所以多次调用同一个函数不会对其他调用该函数的变量造成影响
//incrementByTen和incrementByOne不会应为他们都使用increment而相互影响
incrementByTen() // return 40
incrementByOne() // return 4