在Swift中提供一个可选的默认值?

在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的Optional相同)有这个方法的getOrElse方法:

 val myValue = optionalValue.getOrElse(defaultValue) 

我错过了什么吗? Swift是否已经有了一个紧凑的方法呢? 或者,如果失败了,是否可以在可选的扩展中定义getOrElse

更新

苹果现在增加了一个合并操作符:

 var unwrappedValue = optionalValue ?? defaultValue 

在这种情况下,三元运算符是你的朋友

 var unwrappedValue = optionalValue ? optionalValue! : defaultValue 

您也可以为Optional enum提供自己的扩展:

 extension Optional { func or(defaultValue: T) -> T { switch(self) { case .None: return defaultValue case .Some(let value): return value } } } 

那么你可以做:

 optionalValue.or(defaultValue) 

但是,我build议坚持三元操作符,因为其他开发人员将更快地理解,而不必调查or方法

注意 :我启动了一个模块来添加这样的通用助手, orOptional的swift上添加。

截至2014年8月,Swift有合并运算符(??)允许。 例如,对于一个可选的String myOptional,你可以这样写:

 result = myOptional ?? "n/a" 

以下似乎工作

 extension Optional { func getOrElse<T>(defaultValue: T) -> T { if let value = self? { return value as T } else { return defaultValue } } } 

然而,需要将value as T投入value as T是一个丑陋的黑客。 理想情况下,应该有一种方法来声明T与Optional中包含的types相同。 就像现在这样,根据给定的getOrElse参数input推理集合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 

如果你写道:

 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

我已经做了一个简单的扩展库,并自己使用它来减less这样一个重复的代码。 它将可选的基​​本types转换并返回到默认值。 你只是把它像下面一样,

 CGFloat(optionalValue) 

或具有一定的默认值,

 Int(optionalValue, defaultValue: 100) 

你可以查看这个存储库。