嵌套数组上的Swift相等运算符

时间:2015-10-27 20:22:47

标签: swift

为什么最后一个语句无法使用错误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

2 个答案:

答案 0 :(得分:14)

更新: Swift 4.1中已实施条件一致性。特别是:

  

标准库类型Optional,Array和Dictionary现在符合Equatable协议,当它们的元素类型符合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
如果SimpleEquatable,则

在Xcode 9.3中编译。

(旧答案:) 原因与Why is Equatable not defined for optional arrays中的相似。如果元素类型为==,则可以将 与<{1}}进行比较:

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 也不符合<{1}}协议,请比较Why can't I make Array conform to Equatable?。因此,在

Array<T>

Equatablevar 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运算符

==

或更简单(如@kennytm所建议):

==

这使func ==<Element : Equatable> (lhs: [[Element]], rhs: [[Element]]) -> Bool { return lhs.count == rhs.count && !zip(lhs, rhs).contains {$0 != $1 } } 按预期编译和工作。目前,似乎 无法在任意嵌套的数组上定义func ==<Element : Equatable> (lhs: [[Element]], rhs: [[Element]]) -> Bool { return lhs.elementsEqual(rhs, by: ==) } 运算符。

答案 1 :(得分:1)

您可以通过为其实施==功能来实现,如下所示:

func == (lhs: [[Simple]], rhs: [[Simple]]) -> Bool {
    //your code
}