我有以下实现,我需要访问streetName,如下所示:
if let street = john.residence?.address?.streetName {
street // Darling Lane // This prints string correctly
}
let street = john.residence?.address?.streetName! // Some "Darling Lane" The bang sign // at the end does not forcefully unwraps the optional
有什么理由?
更新:
好的,我现在很困惑!这是完整的代码:
class Person {
var residence :Residence? = Residence()
}
class Residence {
var address :Address? = Address()
}
class Address {
var streetName :String? = "Darling Lane"
var zipCode :String?
var city :String?
}
let street = john.residence?.address?.streetName!
在上面的代码中我说如果居住地不是空的话他们继续前进。当你到达streetName然后给我一个我不在乎的值如果streetName是nil只是抛出错误但是正确评估它。
最后的街道参数包含Some" Darling Lane"而不是"达林巷"。这是为什么?
答案 0 :(得分:2)
您的可选链末尾的!
只会打开可选的streetName
而不是您预期的整个可选链。如果已将streetName
声明为String
类型而非String?
或String!
,则您会收到有关尝试解包非可选值的错误。
如果你这样做了:
let street = (john.residence?.address?.streetName)!
它会起作用。当然,如果residence
,address
或streetName
中的任何一个nil
,您就会崩溃尝试解包nil
。这就是为什么你提出的第一种方法是首选。
回答更新
只有可选变量可以是nil
。这就是为什么可选链的结果必须具有可选类型。
street
的类型是在编译时建立的。编译器看到您有一系列可选项,并使street
属于String?
类型。你在链的末尾打开街道的价值并不重要。由于residence
或address
可能是nil
,因此选项链可能返回nil
,因此编译器必须使street
的类型成为可选如果是结果,它可以保留nil
。
当你这样写:
let street = john.residence?.address?.streetName!
这基本上就是你的代码所做的事情:
var street: String?
if john.residence == nil {
street = nil
} else if john.residence!.address == nil {
street = nil
} else {
// here we have fully unwrapped the street name
// but it is still assigned to street which
// is an optional variable
street = john.residence!.address!.street!
}
唯一的区别在于它是一次性完成的,因此您可以使用let
代替var
。
答案 1 :(得分:1)
发生这种情况的原因是residence
和address
都是选项,因此可选链的评估结果为nil。因此,整个表达式被评估为可选。
要获得非可选值,您必须强行打开所有属性:
let street: String = john.residence!.address!.streetName!
但当然如果该链中的任何选项都是nil,您将获得运行时异常
答案 2 :(得分:1)
代码中的选项是有原因的,如果您已经检查了选项的值,则只需要显式解包变量。如果值不存在,您的应用将崩溃。
立即解开街道名称的正确方法是:
john.residence!.address!.streetName
仅展开residence
和address
,如果其中任何一个未设置,则会引发异常。如果streetName
也是可选的,则您需要在结尾添加另一个!
。
确保您确定自己的数据结构。最好先选择非选项,如果一个人没有residence
或address
,你就需要选项。但如果您使用选项,请确保它们都已经过检查!
Optionals可以使您的代码更安全,更易于阅读,但您必须正确使用它们。