Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 如何展开双选项?_Swift - Fatal编程技术网

Swift 如何展开双选项?

Swift 如何展开双选项?,swift,Swift,如何打开返回为以下格式的字符串: (可选(可选“蓝色”)) cityLabelName打印为(可选“纽约”)试试 var a:String?? = "1" print((a)) if let b = a,c = b{ print(c) } 游乐场截图 也可以强制展开,但它不安全 let d = a!! 给定一个双可选项,例如双包装的字符串: let a: String?? = "hello" print(a as Any) // "Optional(Optional("hello"

如何打开返回为以下格式的字符串:

(可选(可选“蓝色”))

cityLabelName打印为
(可选“纽约”)

试试

var a:String?? = "1"
print((a))
if let b = a,c = b{
    print(c)
}
游乐场截图

也可以强制展开,但它不安全

let d = a!!

给定一个双可选项,例如双包装的
字符串

let a: String?? = "hello"
print(a as Any) // "Optional(Optional("hello"))\n"
@Leo,您可以使用可选绑定两次:

或强制展开两次:

print(value!!)  // don't do this - you're just asking for a crash

您还可以使用以下5种方法安全地展开双面打印:

方法1:

您还可以使用模式匹配:

正如@netigger在中所指出的,这也可以写成:

if case .some(.some(let value)) = a {
    print(value) // "hello\n"
}
虽然不那么简洁,但可能更容易阅读


方法2:

或者,您可以使用零合并运算符两次:

print((a ?? "") ?? "")  // "hello\n"
注意:与此处介绍的其他方法不同,这将始终产生一个值<如果任一选项为
nil
,则使用“(空
字符串


方法3:

或者,您可以使用带有可选绑定的nil合并运算符
??

这是如何工作的?

对于双重包装的可选变量,变量所持有的值可以是以下三项之一:
可选(可选(“某些字符串”))
可选(nil)
(如果内部可选是
nil
),或者
nil
(如果外部可选是
nil
)。那么一个
??无
打开外部可选组件。如果外部可选值为
nil
,则
将其替换为默认值
nil
。如果
a
Optional(nil)
,则
??
将打开外部可选的
nil
。此时,如果内部或外部可选项为
nil
,则将有一个
字符串?
,即
nil
。如果里面有一个
字符串
,您将得到
可选(“某些字符串”)


最后,可选绑定(
if let
)打开
optional(“some string”)
以获取
“some string”
,或者如果其中一个选项为
nil
并跳过该块,则可选绑定失败


方法4:

此外,您还可以使用带有可选绑定的
flatMap


方法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"
}

我必须说被接受的答案非常好,我从这个答案中选择了
方法1
。但是,我想使用不同的语法,使其更具可读性:

if case .some(.some(let value)) = a {
    print(value) // "hello\n"
}
我在
Optional
上做了一个
reduce()
方法,将
可选(可选(U))
转换为
可选(U)
(如Scala中的
展平()
):

Int示例:

// By using reduce() you directly got a standard optional you can unwrap in the standard way (see answer of @vacawama above).
let anInt: Int? = Optional(Optional(5)).reduce()

let unwrapped = anInt ?? 10
我主要在调用一个方法时使用它,该方法可以抛出异常,但在当前上下文中我不想捕获它。例如,读取钥匙链中的用户属性:

let username: String = (try? keychain.get("username")).reduce() ?? "unknown"
这是一个更重要的评论

将双选项视为:

indirect enum S {
  case value(s: S?)
  case none
}
而普通的可选选项如下所示:

enum S {
  case value(s: S)
  case none
}

理解在第一个示例中使用的原因对于所问问题的范围并不重要。没有它就无法编译!在第一个例子中,我只是想说明它的内部类型也是一个可选的类型the
??零
太棒了!这是最好的答案,尤其是方法3。@Raginmari,对于双包装可选变量,变量所持有的值可以是三件事之一:
可选(可选(“某些字符串”)
可选(nil)
如果内部可选是
nil
,或者
nil
如果外部可选是
nil
。所以
a??无
打开外部可选组件。如果外部可选设置为
nil
,则??将其替换为默认值
nil
。如果
a
可选(无)
,则??将打开外包装,留下
nil
。此时,如果内部或外部可选项为
nil
,则得到
nil
。如果里面有一个字符串,您将得到
可选(“某些字符串”)
。最后,可选绑定将打开
可选(“某些字符串”)
,以获得
“某些字符串”
,或者如果其中一个选项为
nil
,则它将失败。方法1和3是我读过的关于该案例的最佳代码片段。谢谢你这么好的帖子!
if case .some(.some(let value)) = a {
    print(value) // "hello\n"
}
extension Optional {
    /// - Returns: Given an Optional(Optional(U)) returns an Optional(U)
    func reduce<U>() -> U? {
        switch self {
        case let unwrapped?:
            return unwrapped as? U
        default:
            return .none
        }
    }
}
// By using reduce() you directly got a standard optional you can unwrap in the standard way (see answer of @vacawama above).
let aString: String? = Optional(Optional("Hello")).reduce()

let unwrapped = aString ?? "Default"
// By using reduce() you directly got a standard optional you can unwrap in the standard way (see answer of @vacawama above).
let anInt: Int? = Optional(Optional(5)).reduce()

let unwrapped = anInt ?? 10
let username: String = (try? keychain.get("username")).reduce() ?? "unknown"
indirect enum S {
  case value(s: S?)
  case none
}
enum S {
  case value(s: S)
  case none
}