2015年9月9日The Swift Programming Language更新内容

来源:互联网 发布:傲娇熊直播 知乎 编辑:程序博客网 时间:2024/06/16 10:46

标签(空格分隔): Swift


此次更新内容

  • 在(闭包一章的)添加了自动闭包(Autoclosures)一节,有@autoclosure属性的信息——还包括它的@autoclosure(escaping)形式。
  • 给Optional Binding一节添加了一个例子:使用了where从句的多个可选绑定。
  • 给String Literalsy一节添加了如下内容:使用“+”操作符在编译阶段是如何将字符字面值联系起来的。
  • 给Metatype Type一节添加了如下内容:comparing metatype values和在结构体的初始化表达式中使用它们。
  • 给Debugging with Assertinons一节添加了一个NOTE:关于如果用户定义的断言不可用的情形。

更新详细

自动闭包

一个自动闭包 是一个被自动创建的闭包,它被包裹在一个表达式中,作为函数的参数被传递。它本身不带有任何的参数,当它被调用时,它会返回它所处的表达式的值。一个自动闭包能让你推迟执行某些代码,因为那部分代码只有你调用闭包的时候才会被执行。正是因为自动闭包能够让你控制什么时候执行其中的代码,所以正好适合那些有副作用或者执行起来颇费力气的代码。下面的代码展示了如何让一个闭包延迟执行。

var customersInLine = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]let nextCustomer = { customersInLine.removeAtIndex(0) }print(customersInLine.count)// prints "5"print("Now serving \(nextCustomer())!")// prints "Now serving Chris!"print(customersInLine.count)// prints "4"

尽管在闭包中customersInLine数组的第一个元素被移除掉了,但是这个操作直到闭包被调用时才会真正执行。如果闭包没有被调用到,表达式中的闭包就永远不会被执行。这里要说明的是nextCustomer的类型不是String而是()->String——一个不带任何参数返回一个字符串的函数。用下面的一个函数,你可以做同样的事情:

// customersInLine is ["Alex", "Ewa", "Barry", "Daniella"]func serveNextCustomer(customer: () -> String) {    print("Now serving \(customer())!")}serveNextCustomer( { customersInLine.removeAtIndex(0) } )// prints "Now serving Alex!"

上面的serverNextCustomer(_:)函数的参数是一个返回下一个客户名字的闭包。下面这个版本的serverNextCustomer(_:)函数做了相同的事情,不同的是没有明确的采用闭包,而是通过给它的参数加@autoclosure标记使用了自动闭包。现在你可以在调用它的时候如同使用一个String,而非闭包。

// customersInLine is ["Ewa", "Barry", "Daniella"]func serveNextCustomer(@autoclosure customer: () -> String) {    print("Now serving \(customer())!")}serveNextCustomer(customersInLine.removeAtIndex(0))// prints "Now serving Ewa!"

NOTE
过度使用自动闭包会让你的代码难以被读懂。根据上下文和函数的名称能够让代码执行被推迟的目的更显而易见。

@autoclosure属性暗含了@noescape属性,它会标明那个闭包只能在特定的函数中使用。也就是说,那个闭包不允许被函数存储,不允许脱离那个函数的作用范围,不允许在那个函数返回后再执行闭包。如果你想要一个自动闭包可以脱离函数的作用范围,那么使用@autoclosure(escaping)标记:

// customersInLine is ["Barry", "Daniella"]var customerClosures: [() -> String] = []func collectCustomerClosures(@autoclosure(escaping) customer: () -> String) {    customerClosures.append(customer)}collectCustomerClosures(customersInLine.removeAtIndex(0))collectCustomerClosures(customersInLine.removeAtIndex(0))print("Collected \(customerClosures.count) closures.")// prints "Collected 2 closures."for customerClosure in customerClosures {    print("Now serving \(customerClosure())!")}// prints "Now serving Barry!"// prints "Now serving Daniella!"

上面的代码中,没有传递一个闭包作为customer参数,而是在collectCustomerClosures(_:)函数中将闭包追加到customerClosures数组中。customerClosures数组在函数的作用域之外定义,这就意味着其中的闭包可以在函数返回后被执行。因此,customer参数必须被允许在函数的作用域之外被执行。

更多的有关@autoclosure@noescape的属性的信息,参见Declaration Attributes.

可选绑定可以使用where从句

可选绑定(Optional Binding)一节的末尾,说明可以在条语句中进行多个可选绑定,做了如下的修改:
原版内容:
单一的一条if语句中可以出现用逗号分隔的多个可选绑定。

if let constantName = someOptional, anotherConstantName = someOtherOptional {    statements}

现在的内容:

单一的一条if语句中可以出现用分号分割的多个可选绑定,而且还可以使用一个where从句判断一个布尔条件:

if let firstNumber = Int("4"), secondNumber = Int("42") where firstNumber < secondNumber {    print("\(firstNumber) < \(secondNumber)")}// prints "4 < 42"

使用断言调试时,断言失效的情况

在这一节的末尾添加了一个NOTE:
断言在代码经过优化编译后会失效,比如说在Xcode中采用一个app目标的默认发布设置进行构建时

关于Metatype Type的修改

由于没有原版本的内容记录,暂时没有做对比。

0 0
原创粉丝点击