给定一个双重可选,例如双重包装String
:
let a: String?? = "hello"
print(a as Any) // "Optional(Optional("hello"))\n"
@Leo, showed你可以使用可选绑定 twice:
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"
}
正如 @netdigger 中指出的他们的答案,也可以写成:
if case .some(.some(let value)) = a {
print(value) // "hello\n"
}
虽然不太简洁,但可能更容易阅读。
方法二:
或者,您可以使用零合并运算符 ??
twice:
print((a ?? "") ?? "") // "hello\n"
Note:与此处介绍的其他方法不同,这始终会产生一个值。""
(empty String
) 如果任一选项为nil
.
方法三:
或者您可以使用零合并运算符 ??
with 可选绑定:
if let value = a ?? nil {
print(value) // "hello\n"
}
这是如何运作的?
对于双重包装的可选,变量保存的值可能是以下三项之一:Optional(Optional("some string"))
, Optional(nil)
如果内部可选是nil
, or nil
如果外部可选是nil
. So a ?? nil
打开外部可选。如果外部可选是nil
, then ??
将其替换为默认值nil
. If a
is Optional(nil)
, then ??
将打开外部可选的离开nil
。此时你将拥有一个String?
那是nil
如果内部或外部可选是nil
。如果有一个String
在里面,你得到Optional("some string")
.
最后,可选绑定 (if let
) 展开Optional("some string")
to get "some string"
or the 可选绑定如果任一选项失败nil
并跳过该块。
方法四:
另外,您可以使用flatMap
with 可选绑定:
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"
}