如何解开双选项? [英] How to unwrap double optionals?
问题描述
你如何解开一个返回的字符串:
How do you unwrap a string that is returned as:
(可选(可选蓝色"))
(Optional(Optional "blue"))
var cityName = String()
if let cityAnno = annotation as MGLAnnotation! {
cityName = String(stringInterpolationSegment: cityAnno.title!)
}
cityLabelName.text = ("\(cityName), \(county)")
cityLabelName 打印为 (可选纽约")
cityLabelName prints out as (Optional "New York")
推荐答案
给定一个双可选的,比如这个双包裹的String
:
Given a double optional such as this doubly wrapped String
:
let a: String?? = "hello"
print(a as Any) // "Optional(Optional("hello"))\n"
@Leo,表明您可以使用两次可选绑定:
@Leo, showed that you could use optional binding 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 种方法可以用来安全地解开双可选:
Here are 5 more methods you can use to safely unwrap a double optional:
方法一:
您也可以使用模式匹配:
if case let value?? = a {
print(value) // "hello\n"
}
正如@netigger 在他们的回答中所指出的,这也可以写成:
As @netigger noted in their answer, this can also be written as:
if case .some(.some(let value)) = a {
print(value) // "hello\n"
}
虽然不那么简洁可能更容易阅读.
which while less concise might be a bit easier to read.
方法二:
或者,您可以使用 nil 合并运算符 ??
两次:
Alternatively, you can use the nil coalescing operator ??
twice:
print((a ?? "") ?? "") // "hello\n"
注意:与此处介绍的其他方法不同,这将始终产生一个值.""
(空 String
) 如果任一选项为 nil
,则使用.
Note: Unlike the other methods presented here, this will always produce a value. ""
(empty String
) is used if either of the optionals is nil
.
方法 3:
或者你可以使用 nil 合并运算符 ??
和 可选绑定:
Or you can use the nil coalescing operator ??
with optional binding:
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")
.
With a doubly wrapped optional, the value held by the variable could be one of 3 things: Optional(Optional("some string"))
, Optional(nil)
if the inner optional is nil
, or nil
if the outer optional is nil
. So a ?? nil
unwraps the outer optional. If the outer optional is nil
, then ??
replaces it with the default value of nil
. If a
is Optional(nil)
, then ??
will unwrap the outer optional leaving nil
. At this point you will have a String?
that is nil
if either the inner or outer optional is nil
. If there is a String
inside, you get Optional("some string")
.
最后,可选绑定(if let
)解开Optional("some string")
得到"some string"
或 optional binding 失败,如果其中一个 optional 是 nil
并跳过块.
Finally, the optional binding (if let
) unwraps Optional("some string")
to get "some string"
or the optional binding fails if either of the optionals is nil
and skips the block.
方法 4:
此外,您可以将 flatMap
与可选绑定一起使用:
Also, you can use flatMap
with optional binding:
if let value = a.flatMap({ $0 }) {
print(value) // "hello\n"
}
<小时>
方法 5:
有条件地将值转换为类型.令人惊讶的是,这将删除所有级别的选项:
Conditionally cast the value to the type. Surprisingly, this will remove all levels of optionals:
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"
}
这篇关于如何解开双选项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!