Running the following code snippet in the playground gives an error:
let a: [Int]? = [1,2]
let b: [Int]? = [1,2]
a == b // value of optional type '[Int]?' not unwrapped; did you mean to use '!' or '?'?
While doing something similar for a 'simpler' optional type works:
var x: Int? = 10
var y: Int?
x == y // false
What is the reasoning behind the first case, of optional arrays, not being allowed? Why can't Swift first see if either side if nil
(.None
) and then if they are not, do the actual array comparison.
The reason it works for simpler types is because there is a version of ==
that is defined for optionals that contain types that are Equatable
:
func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool
But while Int
is Equatable
, Array
is not (because it might contain something that is not equatable - in which case how could it be). All Equatable
things have an ==
operator, but not all things with an ==
operator are Equatable
.
You could write a special-case version of ==
specifically for optional arrays containing equatable types:
func ==<T: Equatable>(lhs: [T]?, rhs: [T]?) -> Bool {
switch (lhs,rhs) {
case (.Some(let lhs), .Some(let rhs)):
return lhs == rhs
case (.None, .None):
return true
default:
return false
}
}
You could also generalize this to cover any collection containing equatable elements:
func ==<C: CollectionType where C.Generator.Element: Equatable>
(lhs: C?, rhs: C?) -> Bool {
switch (lhs,rhs) {
case (.Some(let lhs), .Some(let rhs)):
return lhs == rhs
case (.None, .None):
return true
default:
return false
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With