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函数内解包整个闭包.

时间: 2024-10-18 12:03:09

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

Welcome to Swift (苹果官方Swift文档初译与注解三十五)---248~253页(第五章-- 函数 完)

Function Types as Return Types (函数类型作为返回值类型) 一个函数的类型可以作为另一个函数的返回值类型.可以在一个函数的返回值箭头后面写上一个完整的函数类型. 例如: 下面的例子定义了两个简单的函数,分别为stepForward 和 stepBackward.其中stepForward函数返回值比它的输入值多1,stepBackward函数返回值比它输入值少1.这两个函数的 类型都是(Int) -> Int: func stepForward(input: Int

Welcome to Swift (苹果官方Swift文档初译与注解二十八)---199~208页(第四章-- 流程控制)

Value Bindings (绑定值) 在switch的case中可以绑定一个或者多个值给case体中的临时常量或者变量,这个成为绑定值. 代码样例: let anotherPoint = (2, 0) switch anotherPoint { case (let x, 0):   println("on the x-axis with an x value of \(x)") case (0, let y):   println("on the y-axis with

Welcome to Swift (苹果官方Swift文档初译与注解三十四)---241~247页(第五章-- 函数)

In-Out Parameters (全局参数) 像前面描述的参数变量,只能在函数体内进行修改,如果你需要函数修改的它的参数值,并且希望这些改变在函数调用结束后仍然有效,可以定义使用全局参数. 定义全局参数使用关键字inout,全局参数的值在函数调用的时候进行传递,在函数体内进行修改,最后函数回传新值来替换之前的值. 全局参数在函数中,只能使用变量来当作参数,不能使用常量或者文本值作为参数.因为常量或者文本值不可以被修改.为了表明参数变量可以被修改,要在变量名的前面直接添加一个& 符号. 注意

Welcome to Swift (苹果官方Swift文档初译与注解二十九)---209~218页(第四章-- 流程控制)

Break break语句会立刻结束整个流程控制的执行.break语句可以在switch语句或者循环语句中帮助你提前结束循环或者switch的执行. Break in a Loop Statement  (循环语句中的break) 当在循环语句中使用break,会立刻结束循环的执行,并且跳转到循环体之后的第一行代码.循环不会再遍历执行了. Break in a Switch Statement (switch语句的break) 当在switch语句中使用break,break会立刻结速switc

Welcome to Swift (苹果官方Swift文档初译与注解三十)---225~230页(第五章-- 函数)

Functions (函数) 函数是一个执行特定任务的代码段.通过名称来标识和调用它们. 在Swift中,每个函数都有类型,包括函数的参数类型和返回值类型.这些类型与Swift中的其他类型使用起来一样,这使得函数可以作为参数传递给另一个函数,以及可以从一个函数中返 回函数,一个函数也可以写在另一个函数内部,这样可以更有效的封装和嵌套. Defining and Calling Functions (定义和调用函数) 当你在定义函数的时候,你可以选择性的命名一个或者多个参数类型值,以及函数执行后的

Welcome to Swift (苹果官方Swift文档初译与注解二十二)---148~153页(第三章--集合类型)

在数组的指定索引位置插入一个元素,可以调用数组的insert(atIndex:)方法: shoppingList.insert("Maple Syrup", atIndex: 0) // shoppingList now contains 7 items // "Maple Syrup" is now the first item in the list” 例子中的insert方法在数组的开始位置(索引为0)插入一个新的元素,元素的值是"Maple Syr

Welcome to Swift (苹果官方Swift文档初译与注解二十四)---163~170页(第三章完--第四章 流程控制)

Mutability of Collections (可变集合) 字典和数组都是在一个集合里储存多个值.如果你创建数组或字典后赋值给一个变量,那么这个集合就是可变的( mutable).这就意味着你在创建这个集合之后,依然可以改变这个集合的 大小,添加元素到集合里或者删除已有的元素.相反地,如果你创建的数组或者字典赋值给一个常量,那么这个集合就是不能修改的,也就是说字典或者数组是不可变的(immutable) 对于字典,不可变就意味着你不能替换里面已有的键值对,一个不可变的字典在它一创建出来就是

Welcome to Swift (苹果官方Swift文档初译与注解三十)---219~224页(第四章-- 流程控制 完)

Labeled Statements  (标签语句) 循环或者switch语句可以嵌套其他的循环或者switch,这样在Swift中可以创建复杂的流程控制结构.循环或者switch语句都可以通过break语句来永久的结束,因此,有时候需要显式的 表明在循环或者switch中你需要break的语句.同样的,如果你嵌套多个循环,显式的表明里面的continue语句也是类似的. 为了达成这个目标,可以在循环语句或者switch语句中使用一个语句标签(statement label),利用这个标签和br

Welcome to Swift (苹果官方Swift文档初译与注解三)---11~18页

上述代码中,如果可选值为nil,那么判断条件则为false,而且在{}中的代码将会被忽略,如果可选值不为nil,会将该值逐步运算后赋值给let后面的常量,其中逐步运算过程将依据实际的代码块. Switch 语法支持任何类型数据以及各种比较操作,并不局限在整型. let vegetable = "red pepper" switch vegetable { case "celery": let vegetableComment = "Add some rai