Why does the last statement fail to compile with the error: Binary operator \'==\' cannot be applied to two \'[[Simple]]’ operands
, and is there a way way to mo
Update: Conditional conformance has been implemented in Swift 4.1. In particular:
The standard library types Optional, Array, and Dictionary now conform to the Equatable protocol when their element types conform to Equatable. ...
(from the Swift CHANGELOG).
Arbitrarily nested arrays of Equatable
elements are Equatable
now
and can be compared with ==
. Your code
var x: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]]
var y: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]]
x == y
compiles in Xcode 9.3 if Simple
is Equatable
.
(Old answer:)
The reason is similar as in Why is Equatable not defined for optional arrays. Arrays can be compared with ==
if the element type is Equatable
:
/// Returns true if these arrays contain the same elements.
public func ==<Element : Equatable>(lhs: [Element], rhs: [Element]) -> Bool
That's why
var a: [Simple] = [Simple(message: "a")]
var b: [Simple] = [Simple(message: "a")]
a == b // -> true
compiles.
But even for equatable types T
, Array<T>
does not conform to the Equatable
protocol, compare Why can't I make Array conform to Equatable?. Therefore, in
var x: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]]
var y: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]]
x == y // -> ERROR! Binary operator '==' cannot be applied to two '[[Simple]]’ operands
x
and y
are arrays with the element type [Simple]
which does
not conform to the Equatable
protocol, and there is no
matching ==
operator.
You could define a generic ==
operator for simply nested arrays as
func ==<Element : Equatable> (lhs: [[Element]], rhs: [[Element]]) -> Bool {
return lhs.count == rhs.count && !zip(lhs, rhs).contains {$0 != $1 }
}
or more simply (as suggested by @kennytm):
func ==<Element : Equatable> (lhs: [[Element]], rhs: [[Element]]) -> Bool {
return lhs.elementsEqual(rhs, by: ==)
}
This makes x == y
compile and work as expected. At present, there seems
to be no way to define a ==
operator on arbitrarily nested arrays.
You can do it by implementing a ==
function for it, like following:
func == (lhs: [[Simple]], rhs: [[Simple]]) -> Bool {
//your code
}