Does Swift have a null coalescing operator and if not, what is an example of a custom operator?
As of Swift 2.2 (Xcode 6, beta 5) it's ??
var x: Int?
var y: Int? = 8
var z: Int = x ?? 9000
// z == 9000
z = y ?? 9001
// z == 8
a ?? b
is equivalent to the following code:
a != nil ? a! : b
And as of Beta 6, you can do this:
x ?? y ?? 1 == 8
(Also see blog post)
No, Swift doesn't currently support a null coalescing operator.
Defining Custom Null Coalescing Operator for Swift
A custom operator can be defined for Swift, with the following considerations regarding the Swift language:
Swift and Nil
Swift supports a null concept through its Optional type (a Discriminated Union of sorts) which either holds a value of the underlying type or no value (indicated by nil) and must be explicitly defined as being optional:
var a : String?
A non-optional type can never be nil, or assigned nil. Therefore a custom infix binary NCO can be expected to take an optional as its first parameter.
Available Characters for Custom Operators in Swift
In Swift, custom operators can be comprised of the following characters only:
/ = - + * % < > ! & | ^ . ~
The Operator
Given the choice of available characters, ||| (three pipes, no spacing) isn't terrible (similar to the double pipe OR in Javascript which is used like a NCO):
Using the Operator
var a = String?
var z = a ||| "it's nil!"
println(z) //Output: it's nil!
Defining the Operator
operator infix ||| {}
@infix func |||<T> (left: T?, right: T) -> T {
if let l = left { return l }
return right
}
What Venkat says is correct: there is none but you can define one.
His implementation however is not ideal because he forgot to use @auto_closure
.
Also I believe you can overload ||
without needing to define a new operator.
I do not have the compiler here, but I'll try to give you the code from memory:
func |||<T> (maybe: Optional<T>, defaultValue: @auto_closure () -> T) -> T {
if let some = maybe {
return some
}
return defaultValue()
}
Edit: Thanks to Martin R for testing this with the compiler. See the comments. Apparently overloading ||
is possible but may not work as expected because of the way Swift handles resolution of overloaded operators (which is undocumented and therefore I have no idea if it can be worked around or not). I've changed the function above to use |||
.
I blogged about a custom operator function that provides nil-coalescing here: http://ijoshsmith.com/2014/07/24/nil-coalescing-operator-in-swift/
My choice of operator was !!
which combines the logical not operator (!) and the unwrap operator (!) for a "if cannot unwrap" semantic. Seems I was late to the party, given this thread is already over a month old. Either way, here's my implementation in case you're interested...
operator infix !! {}
@infix func !! <T> (
value: T?,
defaultValue: @auto_closure () -> T)
-> T
{
return value ? value! : defaultValue()
}