您的位置:首页 > 移动开发 > Swift

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

2015-09-12 16:48 477 查看
标签(空格分隔): 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的修改

由于没有原版本的内容记录,暂时没有做对比。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: