如何解包可选<optional <t>&gt;在Swift 1.2中</optional <t>

时间:2015-02-25 16:56:27

标签: swift

假设我们有String??价值。 Optional Optional可能有3种状态:

let strOptOpt1: String?? = .Some(.Some("actual value"))
let strOptOpt2: String?? = .Some(.None)
let strOptOpt3: String?? = .None

为了安全地将它们打包到String,在Swift 1.1中我们可以:

if let str:String = strOptOpt? {
    println(str)
}
else {
    println("was nil") // `.Some(.None)` or `.None`
}

但它在Swift 1.2中不再起作用了:

if let str:String = strOptOpt? {
//                           ^ [!] error: '?' must be followed by a call, member lookup, or subscript

此刻,我想,我必须这样做:

if let strOpt = strOptOpt, str = strOpt {
    println(str)
}

或使用switch

switch strOptOpt {
case let .Some(.Some(str)):
    println(str)
default:
    println("was nil")
}

但是,我认为必须有更简单的方法来做到这一点。有人知道吗?

3 个答案:

答案 0 :(得分:2)

从Swift 2开始,您可以将if/case与模式一起使用,并将x?用作 .Some(x)的同义词:

if case let str?? = strOptOpt1 {
    print(str)
} else {
    print("was nil") // `.Some(.None)` or `.None`
}

答案 1 :(得分:1)

对我来说,我找到的最佳解决方案是在可选绑定中使用??运算符。

let strOptOpt: String?? = ...

if let str = strOptOpt ?? nil {
    println(str) // "actual value"
}

适用于所有这些案件:

  • .Some(.Some("actual value"))
  • .Some(.None)
  • .None

但是,如果strOptOptString???,则应执行以下操作:

let strOptOpt: String??? = ...

if let str = (strOptOpt ?? nil) ?? nil {
    println(str)
}

答案 2 :(得分:0)

在这种情况下,我总是得到双重选择

let field: ChangeField?? = json["field_id"].int.map{ ChangeField(rawValue: $0) }

您可以使用map

代替flatMap
let field: ChangeField? = json["field_id"].int.flatMap{ ChangeField(rawValue: $0) }