Swift-06-闭包

2016-01-18  本文已影响99人  cornerAnt

闭包是自包含的函数代码块,可以被传递和使用,类似OC中的代码块。闭包可以捕获和存储其所在上下文中任意的常量和变量的引用,就是所谓的闭合并包裹着这些常量和变量。


1.闭包表达式

闭包表达式是一种利用简洁语法构建内联包的方式。下面通过多次迭代优化来简化闭包表达式

1.1sort方法

Swift的sort方法可以用来怼数组进行排序,返回一个与原大小数组大小相同,正确排序的新数组,原数组不会被修改


let names = ["zhangsang","lisi","wangwu","zhaoliu"]

// sort方法接受一个闭包,该闭包函数需要传入与数组元素相同的连个值,根据布尔值,来选择排序顺序.
// 类型为(String, String) -> Bool

// 写一个符合该类型的闭包函数,按照逆序排列数组
func backwards(s1: String, s2: String) -> Bool{
    
    return s1 > s2
}
var reversed = names.sort(backwards)
// 排序完的数组如下
["zhaoliu","zhangsang","wangwu","lisi"]

1.2闭包表达式语法

闭包表达式的一般形式

{(参数)-> 返回值 in
     闭包语句
}

闭包表达式的参数

reversed = names.sort({(s1: String, s2: String) -> Bool in return s1 > s2 })

上述代码完全可以写在一行,这样闭包也就变成了内联闭包

1.3根据上下文推断类型

reversed = names.sort({(s1: String, s2: String) -> Bool in return s1 > s2 })


- 该闭包是sort方法的参数,由于该方法的参数必然为(String,String)->Bool 类型的函数,这就意味着闭包的参数和返回值不需要特别指出,Swift可以自动推断出正确的类型。那么,参数和返回值可以继续简写

- ~~~Swift
reversed = names.sort({s1, s2 in return s1 > s2 })

1.4单表达式闭包隐式返回

reversed = names.sort({s1, s2 in  s1 > s2 })

1.5参数名称缩写

reversed = names.sort({ $0 > $1 })


####1.6运算函数
- Swift的Sring类型,(>)接受两个String类型的参数,返回Bool值。这样的类型刚好匹配Sort方法所需的参数类型,因此可以进一步简写
- ~~~Swift
reversed = names.sort(>)

2.尾随闭包

// 一个普通的函数
func oneFunction( closure:()->Void){

    // 函数体
}

// 不用尾随闭包调用
oneFunction { () -> Void in

    // 闭包内容
}
// 使用尾随闭包调用
oneFunction(){
    // 闭包内容
}
reversed = names.sort(){ $1 > $2 }

reversed = names.sort{ $1 > $2 }


- Array有个map(_:)方法,只接受一个闭包作为参数,该方法会返回一个新的数组,数组中的元素与原数组一一映射
- 下面通过该方法,使用尾随闭包,讲Int类型数组[16,58,510]转换为对应的String类型的数组["OneSix","FiveEight","FiveOneZero"]
-
~~~Swift
let digitNames = [
    0: "Zero", 1: "One", 2: "Two",   3: "Three", 4: "Four",
    5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"
]
//
let numbers = [16, 58, 510]
//  目标字符串
let strings = numbers.map { (var number) -> String in
    var output = ""
    while number > 0 {
        output = digitNames[number % 10]! + output
        number /= 10
    }
   return output
}

3.捕获值

下面举个例子来说明:

func makeIncrementor(forIncrement amount: Int) -> () ->Int {

    var runningTotal = 0

    func  incrementor() -> Int{

        runningTotal += amount

        return runningTotal
    }
    return incrementor
}
//
let run = makeIncrementor(forIncrement: 5)
run() // 5
run() // 10
//
let run2 = makeIncrementor(forIncrement: 7)
run2() // 7
//
run() // 15

4.闭包是引用类型

let run3 = run
run3() // 20

5.非逃逸闭包

5.1什么是非逃逸闭包

// 非逃逸闭包
func someFunction(@noescape closure: ()->Void){
    closure()
}
上一篇 下一篇

猜你喜欢

热点阅读