可选链可替代强制解析
通过在想调用的属性、方法、或子脚本的可选值(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)"。
易百教程移动端:请扫描本页面底部(右侧)二维码并关注微信公众号,回复:"教程" 选择相关教程阅读或直接访问:http://m.yiibai.com 。
加QQ群啦,易百教程官方技术学习群
注意:建议每个人选自己的技术方向加群,同一个QQ最多限加 3 个群。
- Java技术群: 227270512 (人数:2000,免费:否)
- Go开发者群(新): 851549018 (人数:1000,免费)
- PHP开发者群: 460153241 (人数:2000,免费)
- MySQL/SQL群: 418407075 (人数:2000,免费:否)
- 大数据开发群: 655154550 (人数:2000,免费:否)
- Python技术群: 287904175 (人数:2000,免费:否)
- 人工智能深度学习: 456236082 (人数:2000,免费:否)
- 测试工程师群: 415553199 (人数:2000,免费:否)
- 前端开发者群: 410430016 (人数:2000,免费:否)
- C/C++技术群(新): 629264796 (人数:2000,免费)
- Node.js技术群(新): 621549808 (人数:2000,免费)
- PostgreSQL数据库群: 539504187 (人数:1000,免费)
- Linux运维技术群: 479429477 (人数:2000,免费:否)
- Oracle数据库: 175248146 (人数:2000,免费:否)
- C#/ASP.Net开发者: 579821706 (人数:2000,免费)
- 数据分析师群: 397883996 (人数:2000,免费:否)