给定一个双重可选,例如这种双重包装的String:
let a: String?? = "hello"
print(a as Any) // "Optional(Optional("hello"))\n"
@Leo, showed 你可以使用两次可选绑定:
if let temp = a, let value = temp {
print(value) // "hello\n"
}
或强制解包两次:
print(value!!) // don't do this - you're just asking for a crash
您可以使用以下 5 种方法来安全地打开双选项:
方法一:
你也可以使用模式匹配:
if case let value?? = a {
print(value) // "hello\n"
}
正如@netigger 在their answer 中指出的那样,这也可以写成:
if case .some(.some(let value)) = a {
print(value) // "hello\n"
}
虽然不太简洁,但可能更容易阅读。
方法二:
或者,您可以使用 nil 合并运算符 ?? 两次:
print((a ?? "") ?? "") // "hello\n"
注意:与此处介绍的其他方法不同,这将始终产生一个值。 ""(空的String)如果有一个选项是nil,则使用。
方法三:
或者您可以使用 nil 合并运算符 ?? 和 可选绑定:
if let value = a ?? nil {
print(value) // "hello\n"
}
这是如何工作的?
使用双重包装的可选项,变量持有的值可以是以下三项之一:Optional(Optional("some string")),Optional(nil),如果内部可选项是nil,或者nil,如果外部可选项是nil .所以 ?? nil 解开外部可选。如果外部可选项为nil,则?? 将其替换为默认值nil。如果a 是Optional(nil),那么?? 将展开外部可选,留下nil。此时,如果内部或外部可选选项为nil,您将拥有String?,即nil。如果里面有String,你会得到Optional("some string")。
最后,可选绑定 (if let) 解包Optional("some string") 以获取"some string" 或可选绑定 失败,如果其中任何一个选项是nil并跳过该块。
方法四:
另外,您可以将flatMap 与可选绑定一起使用:
if let value = a.flatMap({ $0 }) {
print(value) // "hello\n"
}
方法五:
有条件地将值转换为类型。令人惊讶的是,这将删除所有级别的选项:
let a: String?? = "hello"
let b: String??????? = "bye"
if let value = a as? String {
print(value) // "hello\n"
}
print(b as Any) // "Optional(Optional(Optional(Optional(Optional(Optional(Optional("bye")))))))\n"
if let value = b as? String {
print(value) // "bye\n"
}