在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
方法
注意 :我启动了一个模块来添加这样的通用助手, or
在Optional
的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)
你可以查看这个存储库。