为什么Swift编译器希望我写
if let addressNumber = paul.residence?.address?.buildingNumber?.toInt() {
}
而不仅仅是写作:
if let addressNumber = paul.residence.address.buildingNumber.toInt() {
}
编译器显然具有静态类型信息来处理可选值和每个后续值的第一次取消引用的条件语句。
以下陈述为什么不继续这样做?
答案 0 :(得分:4)
每个属性都是可选属性。它可能是有效的,也可能是“不存在”(零)。与ObjC不同,Swift将nil-references视为崩溃,除非你使它们成为条件。我认为这是出于卫生和性能原因,但无论如何,这都是语言所施加的限制。
答案 1 :(得分:0)
如果每个对象的属性声明不是可选的,那么您发布的第二个声明是可能的。
例如:
class Person {
var residence: Residence?
}
class Residence {
var address: Address?
}
class Address {
var buildingNumber:String?
var streetName:String?
var apptNumber:UInt?
}
此代码需要您添加条件标记,以确保您尝试访问的包装属性不是nil
。
请注意,由于?
推断默认值为nil
,因此没有为这些可选类型设置初始值。
class Person {
var residence: Residence
init(residence: Residence) {
self.residence = residence
}
}
class Residence {
var address: Address
init(address: Address) {
self.address = address
}
}
class Address {
var buildingNumber:String
var streetName:String
var apptNumber:UInt
init(buildingNumber: String, streetName: String, apptNumber: UInt) {
self.buildingNumber = buildingNumber
self.streetName = streetName
self.apptNumber = apptNumber
}
}
在第二个版本中,初始化程序会强制您为每个属性设置一个非零值。对于要初始化的对象,还需要初始化其所有属性。可选项具有预先初始化为nil的便利性。
另请注意,所有?
都已从Person
,Residence
和Address
的属性声明中删除。
如果您的代码是以这种方式构建的,那么您的第二个if let
语句可以正常运行。但话说回来,在第二种情况下,没有必要打开你的选项(你没有任何东西)。你可以简单地打电话:
paul.residence.address.buildingNumber.toInt()
获得你的价值。
我可能会补充一点,使用选项会更安全,因为它不会强迫您使用类的每个属性。
答案 2 :(得分:0)
一种看待它的方法是if let
是一种免于检查nils的简单方法,没有可选的它是没有意义的。