Swift闭包函数(Array)

闭包概述:(以下是我拷贝的)

闭包(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

你可能感兴趣的:(Swift闭包函数(Array))