首页 > 代码库 > Welcome to Swift (苹果官方Swift文档初译与注解三十八)---266~271页(第六章-- 闭包)

Welcome to Swift (苹果官方Swift文档初译与注解三十八)---266~271页(第六章-- 闭包)

Trailing Closures(尾闭包)

  如果你需要将一个闭包表达式作为参数传递给一个函数,而且参数的位置刚刚好是函数的最后一个,你这个闭包表达式又很长,那么使用尾闭包就显得非常有效(有用).

尾闭包是一个写在跟随函数()外面(或后面)的闭包表达式:

  func someFunctionThatTakesAClosure(closure: () -> ()) {

      // function body goes here

  }

   // here‘s how you call this function without using a trailing closure:

   someFunctionThatTakesAClosure({

      // closure‘s body goes here

      })

   // here‘s how you call this function with a trailing closure instead:

   someFunctionThatTakesAClosure() {

      // trailing closure‘s body goes here

  }

  注意点:

  如果一个闭包表达式是函数的唯一参数,而且你又使用了尾闭包的方式,那么你在调用函数的时候,可以只使用函数名,而不用写上一对小括号()

  前面提过的字符串排序闭包,就可以使用尾闭包的方式:

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

  当闭包表达式非常长,以至于一行无法写完的情况下,尾闭包就会显得非常有用.举个例子,Swift中的Array类型有一个map方法,它接收一个闭包表达式作为一个参数,  在数组内每个元素都调用一次这个闭包,返回一个针对这个元素修改过的map值(可能是其他类型),这些都根据闭包来指定.

  在对数组中每个元素应用了闭包之后,map方法返回一个新数组,它包含新的映射值与原数组序列相同.

  下面例子告诉你如何使用尾闭包形式的map方法来将int数组转换成String数组.数组[16,58,510]是用了创建一下新数组["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]

  上面代码创建了从数字到英文版本的一个映射字典,它也定义了整型数组,准备用来转换成字符串.

  你现在可以使用numbers数组创建一个String数组,通过传递一个闭包表达式作为数组map方法的尾闭包.需要注意的是,调用numbers.map的时候,不需要在map后  面写小括号()了,这是因为map方法只有一个参数,而这个传进来的刚刚好又是尾闭包:

    let strings = numbers.map {

        (var number) -> String in

        var output = ""

        while number > 0 {

            output = digitNames[number % 10]! + output

            number /= 10

        }

        return output

    }

    // strings is inferred to be of type String[]

    // its value is ["OneSix", "FiveEight", "FiveOneZero"]

  map函数调用闭包表达式来处理每个数组中的元素.你不需要指定闭包的输入参数类型,因为具体类型会根据数组中元素的值自动判定.

  在这个例子里,闭包的number参数定义为一个可变参数,因此参数的值在闭包内是可以进行修改的,而不用重新声明一个新的局部变量,再给这个局部变量传递number  的值,而且闭包表达式也指定了返回值类型String.

  这个闭包表达式每次在被调用的时候,创建一个叫output的字符串,它计算number最后位上的数(通过number%10这个操作),让后用这个数字在字典digitNames中查  找对应的字符串.

  注意点:

   调用字典的digitNames时候后面跟了一个感叹号!,是因为这个方法返回一个可选值,用来表示如果字典中键不存在的时候,查找失败.在上面的例子里,它保证了    number%10总是合法的健,而且感叹号!会对存储在可选值里的字符串进行强制解包.

  从字典digitNames中接收到的字符串被添加到output前面,这样就有效的建立了一个反序的字符串(表达式number%10,会给出16里面的6,58里面的8,510里面的0)

  然后变量number除以10,由于它是一个整型,所以结果也是整型,因此16会变成1,58会变成5,510会变成51.

  这个过程会一直重复,直到number/=10这个值等于0,这时候output会被闭包返回,然后map函数会将它添加到output数组.

  在上面例子里,尾闭包语法的使用,很简洁的封装了闭包功能,不需要在map函数内解包整个闭包.

 

Welcome to Swift (苹果官方Swift文档初译与注解三十八)---266~271页(第六章-- 闭包)