为什么最后一个语句无法编译并显示错误: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中实现了条件一致性。 特别是:
(来自Swift CHANGELOG)。Equatable
元素的任意嵌套数组现在是Equatable
可以与==
进行比较。您的验证码
var x: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]]
var y: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]]
x == y
如果
Simple
是Equatable
,则在Xcode 9.3中编译。(旧答案:)
原因类似于Why is Equatable not defined for optional arrays中的原因。如果元素类型为
==
,则可以将数组与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
编译。
但是,即使对于等于类型的
T
,Array<T>
不符合Equatable
协议(protocol),请比较Why can't I make Array conform to Equatable?。因此,在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
协议(protocol),并且没有匹配的
==
运算符。您可以为简单的嵌套数组定义一个通用的
==
运算符,如下所示: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
可以按预期进行编译和工作。目前看来不能在任意嵌套的数组上定义
==
运算符。