为什么最后一条语句无法编译并出现错误:二元运算符'=='不能应用于两个'[[Simple]]'操作数
,有没有办法修改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 中实现。特别是:
The standard library types Optional, Array, and Dictionary now conform to the Equatable protocol when their element types conform to Equatable. ...
(来自 Swift CHANGELOG )。
任意嵌套的 Equatable
数组元素是 Equatable
现在
可以与 ==
进行比较。您的代码
var x: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]]
var y: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]]
x == y
在 Xcode 9.3 中编译 if Simple
是 Equatable
.
(旧答案:)
原因与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
编译并按预期工作。目前看来,有
无法定义==
任意嵌套数组上的运算符。
关于嵌套数组上的 Swift 相等运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39923357/