I'm trying to write a function to unwrap optionals with an arbitrary number of levels of nesting. Here's the test I'm using:
let a: Int??? = 1
let b: Int??? = nil
print(a.unwrap(0), b.unwrap(0)) // should print 1, 0
I can get the correct output with a basic generic function:
extension Optional {
func unwrap<T> (_ defaultValue: T) -> T {
return (self as? T) ?? defaultValue
}
}
print(a.unwrap(0), b.unwrap(0)) // 1, 0
But this doesn't prevent the function from being called with a different type than the optional. For instance, I could call a.unwrap("foo")
and it would print "foo" instead of "1" since of course you can't cast Int???
to String
.
I tried it using Wrapped
instead, which semi-properly restricts the default value but doesn't give the correct output:
extension Optional {
func unwrap (_ defaultValue: Wrapped) -> Wrapped {
return (self as? Wrapped) ?? defaultValue
}
}
print(a.unwrap(0), b.unwrap(0)) // Optional(Optional(1)), nil
It only unwraps one level of the optional, instead of all three, and since nil is a valid value for Int??
it doesn't return the default.
Is there any way to safely do what I want here?
if defaultValue is Wrapped { return (self as? T) ?? defaultValue } else { fatalError("Type mismatch") }
– Kamran