为什么最后一个语句无法编译为错误:Binary operator '==' cannot be applied to two '[[Simple]]’ operands,并且有一种方法可以修改Simple结构或扩展==运算符以对嵌套数组(或字典)执行相等性检查?
Binary operator '==' cannot be applied to two '[[Simple]]’ operands
Simple
==
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
更新: 条件一致性已在 Swift 4.1中 实现 。 特别是:
现在,标准库类型Optional,Array和Dictionary的元素类型符合Equatable时,它们便符合Equatable协议。…
(来自Swift CHANGELOG)。
现在可以任意嵌套Equatable元素数组,Equatable并且可以与进行比较==。您的密码
Equatable
var x: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]] var y: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]] x == y
如果Simple为,则在Xcode 9.3中编译Equatable。
(旧答案:) 其原因与为什么未为可选数组定义Equatable相似。如果元素类型为,则可以 与 数组进行 比较 :==``Equatable
==``Equatable
/// Returns true if these arrays contain the same elements. public func ==<Element : Equatable>(lhs: [Element], rhs: [Element]) -> Bool
这就是为什么
var a: [Simple] = [Simple(message: "a")] var b: [Simple] = [Simple(message: "a")] a == b // -> true
编译。
但即使是equatable类型T,Array<T> 不符合 该Equatable协议,比较为什么我不能做阵列符合Equatable?。因此,在
T
Array<T>
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和y与元素类型阵列[Simple],其不会 不 符合Equatable协议,并且不存在匹配的==运算符。
x
y
[Simple]
您可以==为简单的嵌套数组定义通用运算符,如下所示:
func ==<Element : Equatable> (lhs: [[Element]], rhs: [[Element]]) -> Bool { return lhs.count == rhs.count && !zip(lhs, rhs).contains {$0 != $1 } }
或更简单(如@kennytm所建议):
func ==<Element : Equatable> (lhs: [[Element]], rhs: [[Element]]) -> Bool { return lhs.elementsEqual(rhs, by: ==) }
这样可以进行x == y编译并按预期工作。目前,似乎没有办法==在任意嵌套的数组上定义运算符。
x == y