A few nice things this morning
// See: http://twitter.com/iMartinKiss/status/494456905885319169 extension Optional { func unwrap(#defaultValue: @auto_closure () -> T) -> T { return self ? self! : defaultValue() } } // See: http://ijoshsmith.com/2014/07/24/nil-coalescing-operator-in-swift/ operator infix !! {} @infix func !! <T> (value: T?, defaultValue: @auto_closure () -> T) -> T { return value ? value! : defaultValue() }
And from Phil Holland:
func defaultFallback<T>(a: T?, b: @auto_closure () -> T) -> T { return a ? a! : b() } func defaultFallback<T: LogicValue>(a: T, b: @auto_closure () -> T) -> T { return a ? a : b() } func defaultFallback<T: Integer>(a: T, b: @auto_closure () -> T) -> T { return (a != T.allZeros) ? a : b() } func defaultFallback<T: FloatingPointNumber>(a: T, b: @auto_closure () -> T) -> T { return (!a.isZero && !a.isNaN) ? a : b() }
4 Comments
The !! operator (or |||, which is the other thing people use) should be made right-associative (IIRC). That allows you to create a chain of several possibly-optional defaults, ending with a non-optional last default, like “this !! that !! theOther !! 0”.
It should probably also be set to the same precedence as the logical operators, but I haven’t looked up what precedence level they’re at.
I went with 100 for mine (which happens to be the default as well) because that’s the precedence of the ?: ternary. The || and && operators are precedence 110 and 120 (respectively), but they’re also left-associative.
Ideally Swift would provide a `x ?: y` shorthand for this operator, similar to C’s ?: shorthand, which would presumably be right-associatve precedence 100. I filed a radar on this already.
For the !! operator, my preference is !||, which I posted a gist of at https://gist.github.com/kballard/5fa08916c1f480bae38d.
Also the `unwrap` method, while cute, doesn’t work for any type `T?!`. It will unwrap the outer implicitly-unwrapped optional and call the `unwrap()` method on the inner `T?` instead. Presumably you could write a similar extension on ImplicitlyUnwrappedOptional, though I haven’t tested that.
For some reason this doesn’t happen with operators. `T?!` will be converted to `T??` when used with the operator version (like the one I linked to).