假设我们有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")
}
但是,我认为必须有更简单的方法来做到这一点。有人知道吗?
答案 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
但是,如果strOptOpt
为String???
,则应执行以下操作:
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) }