如何打开双重选项?

Phi*_*ews 35 swift

如何解包返回的字符串:

(可选(可选"蓝色"))

    var cityName = String()

    if let cityAnno = annotation as MGLAnnotation! {

        cityName = String(stringInterpolationSegment: cityAnno.title!)

    }

cityLabelName.text = ("\(cityName), \(county)")
Run Code Online (Sandbox Code Playgroud)

cityLabelName打印为(可选"纽约")

vac*_*ama 115

给出一个双重可选,例如这个双重包裹String:

let a: String?? = "hello"
print(a as Any) // "Optional(Optional("hello"))\n"
Run Code Online (Sandbox Code Playgroud)

@Leo,表明你可以使用两次可选绑定:

if let temp = a, let value = temp {
    print(value) // "hello\n"
}
Run Code Online (Sandbox Code Playgroud)

或强行打开两次:

print(value!!)  // don't do this - you're just asking for a crash
Run Code Online (Sandbox Code Playgroud)

这里有5种方法可以用来安全地解开双重选项:

方法1:

您还可以使用模式匹配:

if case let value?? = a {
    print(value) // "hello\n"
}
Run Code Online (Sandbox Code Playgroud)

正如@netigger在答案中指出的那样,这也可以写成:

if case .some(.some(let value)) = a {
    print(value) // "hello\n"
}
Run Code Online (Sandbox Code Playgroud)

虽然不那么简洁可能会更容易阅读.


方法2:

或者,您可以使用nil coalescing运算符 ??两次:

print((a ?? "") ?? "")  // "hello\n"
Run Code Online (Sandbox Code Playgroud)

注意:与此处介绍的其他方法不同,这将始终生成一个值. 如果任一选项是,则使用""(空String)nil.


方法3:

或者您可以使用nil coalescing运算符 ??可选绑定:

if let value = a ?? nil {
    print(value)  // "hello\n"
}
Run Code Online (Sandbox Code Playgroud)

这是如何运作的?

用双重包裹可选的,由变量保持的值可以是3件事情之一:Optional(Optional("some string")),Optional(nil)如果内可选的是nil,或nil如果外可选的是nil.所以?? nil打开外部可选项.如果外部可选项是nil,则将其??替换为默认值nil.如果aOptional(nil),那么??将打开外部可选的离开nil.此时String?,nil如果是内部或外部可选项,则会有一个nil.如果有一个String内部,你得到Optional("some string").

最后,如果任一选项是并且跳过块,则可选的绑定(if let)展开Optional("some string")以获取"some string"可选的绑定失败nil.


方法4:

此外,您还可以使用flatMap带有可选的结合:

if let value = a.flatMap({ $0 }) {
    print(value)  // "hello\n"
}
Run Code Online (Sandbox Code Playgroud)

方法5:

有条件地将值转换为类型.令人惊讶的是,这将删除所有级别的选项:

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"
}
Run Code Online (Sandbox Code Playgroud)

  • `?? nil`很棒! (20认同)
  • 这是最好的答案,尤其是方法3. (3认同)
  • 方法 1 和 3 是我在案例中读到的最好的代码片段。谢谢你这么棒的帖子! (2认同)

Leo*_*Leo 5

尝试

var a:String?? = "1"
print((a))
if let b = a,c = b{
    print(c)
}
Run Code Online (Sandbox Code Playgroud)

操场截图

在此输入图像描述

你也可以强行打开包装,但它不安全

let d = a!!
Run Code Online (Sandbox Code Playgroud)