swift学习:13.闭包

来源:互联网 发布:samsung gear软件下载 编辑:程序博客网 时间:2024/06/06 13:05

本页包含内容:

  • 闭包表达式(Closure Expressions)
  • 尾随闭包(Trailing Closures)
  • 值捕获(Capturing Values)
  • 闭包是引用类型(Closures Are Reference Types)

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, s2in return s1 > s2 } )

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

reversed =sorted(names, { s1, s2in 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

    }

    returnincrementor

}

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
原创粉丝点击