在Swift中处理选项的习惯用法似乎过于冗长,如果您想要做的就是提供一个默认值,如果它没有:
if let value = optionalValue {
// do something with 'value'
} else {
// do the same thing with your default value
}
涉及不必要地复制代码,或
var unwrappedValue
if let value = optionalValue {
unwrappedValue = value
} else {
unwrappedValue = defaultValue
}
要求unwrappedValue
不是常数。
Scala的Option monad(与Swift的可选基本相同)为此目的使用方法getOrElse
:
val myValue = optionalValue.getOrElse(defaultValue)
我错过了什么吗?斯威夫特有一个紧凑的方式吗?或者,如果失败,是否可以在Optional的扩展名中定义getOrElse
?
答案 0 :(得分:251)
<强>更新强>
Apple现在添加了一个合并运算符:
var unwrappedValue = optionalValue ?? defaultValue
在这种情况下,三元运算符是你的朋友
var unwrappedValue = optionalValue ? optionalValue! : defaultValue
您还可以为Optional枚举提供自己的扩展名:
extension Optional {
func or(defaultValue: T) -> T {
switch(self) {
case .None:
return defaultValue
case .Some(let value):
return value
}
}
}
然后你可以这样做:
optionalValue.or(defaultValue)
但是,我建议坚持使用三元运算符,因为其他开发人员可以更快地理解,而无需调查or
方法
注意:我开始module在or
上添加Optional
这样的常见帮助,以便迅速添加。
答案 1 :(得分:23)
截至2014年8月,Swift拥有合并运算符(??)。例如,对于可选的String myOptional,您可以编写:
result = myOptional ?? "n/a"
答案 2 :(得分:3)
如果你写了:
let result = optionalValue ?? 50
和optionalValue != nil
然后result
也将是optional
,您将来需要打开它
但你可以编写运算符
infix operator ??? { associativity left precedence 140 }
func ???<T>(optLeft:T?, right:T!) -> T!
{
if let left = optLeft
{
return left
}
else { return right}
}
现在你可以:
let result = optionalValue ??? 50
当optionalValue != nil
时,result
将为unwraped
答案 3 :(得分:2)
以下似乎有效
extension Optional {
func getOrElse<T>(defaultValue: T) -> T {
if let value = self? {
return value as T
} else {
return defaultValue
}
}
}
然而,投射value as T
的需要是一个丑陋的黑客。理想情况下,应该有一种方法断言T
与Optional中包含的类型相同。就目前而言,根据给予getOrElse的参数键入推理集T
,如果这与Optional不匹配,则在运行时失败,而Optional是非零的:
let x: Int?
let y = x.getOrElse(1.414) // y inferred as Double, assigned 1.414
let a: Int? = 5
let b: Double = a.getOrElse(3.14) // Runtime failure casting 5 to Double
答案 4 :(得分:0)
如果你想用一个字符串来做到这一点,你可以这样做..
string1 = string2.isEmpty ? "Default Value":string2