发布于 2015-06-14 01:44:28 | 204 次阅读 | 评论: 0 | 来源: 网络整理
通过在想调用的属性、方法、或子脚本的可选值(optional value
)(非空)后面放一个问号,可以定义一个可选链。这一点很像在可选值后面放一个叹号来强制拆得其封包内的值。它们的主要的区别在于当可选值为空时可选链即刻失败,然而一般的强制解析将会引发运行时错误。
为了反映可选链可以调用空(nil
),不论你调用的属性、方法、子脚本等返回的值是不是可选值,它的返回结果都是一个可选值。你可以利用这个返回值来检测你的可选链是否调用成功,有返回值即成功,返回nil则失败。
调用可选链的返回结果与原本的返回结果具有相同的类型,但是原本的返回结果被包装成了一个可选值,当可选链调用成功时,一个应该返回Int
的属性将会返回Int?
。
下面几段代码将解释可选链和强制解析的不同。
首先定义两个类Person
和Residence
。
class Person {
var residence: Residence?
}
class Residence {
var numberOfRooms = 1
}
Residence
具有一个Int
类型的numberOfRooms
,其值为 1。Person
具有一个可选residence
属性,它的类型是Residence?
。
如果你创建一个新的Person
实例,它的residence
属性由于是被定义为可选型的,此属性将默认初始化为空:
let john = Person()
如果你想使用感叹号(!
)强制解析获得这个人residence
属性numberOfRooms
属性值,将会引发运行时错误,因为这时没有可以供解析的residence
值。
let roomCount = john.residence!.numberOfRooms
//将导致运行时错误
当john.residence
不是nil
时,会运行通过,且会将roomCount
设置为一个int
类型的合理值。然而,如上所述,当residence
为空时,这个代码将会导致运行时错误。
可选链提供了一种另一种获得numberOfRooms
的方法。利用可选链,使用问号来代替原来!
的位置:
if let roomCount = john.residence?.numberOfRooms {
println("John's residence has (roomCount) room(s).")
} else {
println("Unable to retrieve the number of rooms.")
}
// 打印 "Unable to retrieve the number of rooms.
这告诉 Swift 来链接可选residence?
属性,如果residence
存在则取回numberOfRooms
的值。
因为这种尝试获得numberOfRooms
的操作有可能失败,可选链会返回Int?
类型值,或者称作“可选Int
”。当residence
是空的时候(上例),选择Int
将会为空,因此会出先无法访问numberOfRooms
的情况。
要注意的是,即使numberOfRooms是非可选Int
(Int?
)时这一点也成立。只要是通过可选链的请求就意味着最后numberOfRooms
总是返回一个Int?
而不是Int
。
你可以自己定义一个Residence
实例给john.residence
,这样它就不再为空了:
john.residence = Residence()
john.residence
现在有了实际存在的实例而不是nil了。如果你想使用和前面一样的可选链来获得numberOfRoooms
,它将返回一个包含默认值 1 的Int?
:
if let roomCount = john.residence?.numberOfRooms {
println("John's residence has (roomCount) room(s).")
} else {
println("Unable to retrieve the number of rooms.")
}
// 打印 "John's residence has 1 room(s)"。