The idiom for dealing with optionals in Swift seems excessively verbose, if all you want to do is provide a default value in the case where it\'s nil:
if let
if you wrote:
let result = optionalValue ?? 50
and optionalValue != nil
then result
will be optional
too and you will need unwrap it in future
But you can write operator
infix operator ??? { associativity left precedence 140 }
func ???<T>(optLeft:T?, right:T!) -> T!
{
if let left = optLeft
{
return left
}
else { return right}
}
Now you can:
let result = optionalValue ??? 50
And when optionalValue != nil
then result
will be unwraped
Update
Apple has now added a coalescing operator:
var unwrappedValue = optionalValue ?? defaultValue
The ternary operator is your friend in this case
var unwrappedValue = optionalValue ? optionalValue! : defaultValue
You could also provide your own extension for the Optional enum:
extension Optional {
func or(defaultValue: T) -> T {
switch(self) {
case .None:
return defaultValue
case .Some(let value):
return value
}
}
}
Then you can just do:
optionalValue.or(defaultValue)
However, I recommend sticking to the ternary operator as other developers will understand that much more quickly without having to investigate the or
method
Note: I started a module to add common helpers like this or
on Optional
to swift.
The following seems to work
extension Optional {
func getOrElse<T>(defaultValue: T) -> T {
if let value = self? {
return value as T
} else {
return defaultValue
}
}
}
however the need to cast value as T
is an ugly hack. Ideally, there should be a way to assert that T
is the same as the type contained in the Optional. As it stands, type inferencing sets T
based on the parameter given to getOrElse, and then fails at runtime if this does not match the Optional and the Optional is non-nil:
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
As of Aug 2014 Swift has coalescing operator (??) that allows that. For example, for an optional String myOptional you could write:
result = myOptional ?? "n/a"