swift学习:13.闭包

本页包含内容:

1.闭包表达式

Swift标准库提供了sorted函数,会根据您提供的基于输出类型排序的闭包函数将已知类型数组中的值进行排序。 一旦排序完成,函数会返回一个与原数组大小相同的新数组,该数组中包含已经正确排序的同类型元素。

func sorted(array: [String] , compareFunc:

    (String,String)->Bool) -> [String]{

        var target:[String] = array

        for i in 0..<target.count{

            for j in i+1..<target.count{

                if compareFunc(target[i],target[j]){

                    let index = target[i]

                    target[i] = target[j]

                    target[j] = index

                }

            }

        }

        return target

}

下面的闭包表达式实例用sorted函数对一个String类型的数组进行排序,下面是初始数组值:

let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]

func backwards(s1: String, s2: String) -> Bool {

    return s1 > s2

}

var reversed = sorted(names, backwards)

这是一个相当冗长的方式,本质上只是写了一个单表达式函数 (a > b)。 在下面的例子中,利用闭合表达式语法可以更好的构造一个内联排序闭包。

下面的例子展示了之前backwards函数对应的闭包表达式版本的代码:

reversed = sorted(names, { (s1: String, s2: String) -> Bool in

    return s1 > s2

})

//第一步简化:参数类型可以上下文推导

reversed = sorted(names, { s1, s2 in return s1 > s2 } )

//第二步简化:只有一行的闭包可以省略return

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

//第三步简化:$0,$1,$2可以依次表示函数参数

reversed = sorted(names, { $0 > $1 } )

//第四步简化:SwiftString类型定义了关于(>)的字符串实现

reversed = sorted(names, >)

2.尾随闭包

如果您需要将一个很长的闭包表达式作为最后一个参数传递给函数,可以使用尾随闭包来增强函数的可读性。 尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用。在上例中作为sorted函数参数的字符串排序闭包可以改写为:

reversed = sorted(names) { $0 > $1 }

下例介绍了如何在map方法中使用尾随闭包将Int类型数组[16,58,510]转换为包含对应String类型的数组["OneSix", "FiveEight", "FiveOneZero"]:


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 incrementByTen = makeIncrementor(forIncrement: 10)

incrementByTen()

// 返回的值为10

incrementByTen()

// 返回的值为20

incrementByTen()

// 返回的值为30

let incrementBySeven = makeIncrementor(forIncrement: 7)

incrementBySeven()

// 返回的值为7

incrementByTen()

// 返回的值为40

4.闭包是引用类型

上面的例子中,incrementBySevenincrementByTen是常量,但是这些常量指向的闭包仍然可以增加其捕获的变量值。 这是因为函数和闭包都是引用类型。 这也意味着如果您将闭包赋值给了两个不同的常量/变量,两个值都会指向同一个闭包:

let alsoIncrementByTen = incrementByTen

alsoIncrementByTen()

// 返回的值为50


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值