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 modify the Simple
struct or extend the ==
operator to be able to perform equality checks on nested arrays (or dictionaries)?
var i1: [Int] = [1]
var i2: [Int] = [1]
i1 == i2 // -> true
var i3: [[Int]] = [[1], [2]]
var i4: [[Int]] = [[1], [2]]
i3 == i4 // -> true
struct Simple: Equatable, Hashable {
let message: String
var hashValue: Int {
return message.hashValue
}
}
func ==(lhs: Simple, rhs: Simple) -> Bool {
return lhs.message == rhs.message
}
var a: [Simple] = [Simple(message: "a")]
var b: [Simple] = [Simple(message: "a")]
a == b // -> true
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
Update: Conditional conformance has been implemented in Swift 4.1. In particular:
(from the Swift CHANGELOG).
Arbitrarily nested arrays of
Equatable
elements areEquatable
now and can be compared with==
. Your codecompiles in Xcode 9.3 if
Simple
isEquatable
.(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 isEquatable
:That's why
compiles.
But even for equatable types
T
,Array<T>
does not conform to theEquatable
protocol, compare Why can't I make Array conform to Equatable?. Therefore, inx
andy
are arrays with the element type[Simple]
which does not conform to theEquatable
protocol, and there is no matching==
operator.You could define a generic
==
operator for simply nested arrays asor more simply (as suggested by @kennytm):
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: