24

我有一个带有协议的课程Equatable。该类如下所示:

class Item: Equatable {

    let item: [[Modifications: String]]

    init(item: [[Modifications: String]]) {
        self.item = item
    }
}

func ==(lhs: Item, rhs: Item) -> Bool {
    return lhs.item == rhs.item
}

但这给了我错误(见标题)。该物业item[[String: String]]以前的,没有问题,我不知道如何解决这个问题。我尝试在整个 SO 上进行谷歌搜索和搜索,但没有运气..

枚举只是一个简单的基本枚举:

enum Modifications: Int {
    case Add    = 1
    case Remove = 2
    case More   = 3
    case Less   = 4
}
4

2 回答 2

24

更新: SE-0143 条件一致性已在Swift 4.2 中实现。

因此,您的代码现在可以编译。如果你定义Item为一个结构

struct Item: Equatable {
    let item: [[Modifications: String]]

    init(item: [[Modifications: String]]) {
        self.item = item
    }
}

然后编译器==自动合成运算符,比较SE-0185 Synthesizing Equatable 和 Hashable 的一致性


(前 Swift 4.1 答案:)

问题是即使==是为字典类型定义的 [Modifications: String],该类型也不符合 Equatable。因此数组比较运算符

public func ==<Element : Equatable>(lhs: [Element], rhs: [Element]) -> Bool

不能应用于[[Modifications: String]]

==for的一个可能的简洁实现Item

func ==(lhs: Item, rhs: Item) -> Bool {
    return lhs.item.count == rhs.item.count 
           && !zip(lhs.item, rhs.item).contains {$0 != $1 }
}

您的代码编译为[[String: String]]- 如果 Foundation 框架被导入,正如@user3441734 正确所说的那样 - 因为 then[String: String]会自动转换为NSDictionary符合 Equatable. 这是该声明的“证明”:

func foo<T : Equatable>(obj :[T]) {
    print(obj.dynamicType)
}

// This does not compile:
foo( [[Modifications: String]]() )

// This compiles, and the output is "Array<NSDictionary>":
foo( [[String: String]]() )
于 2016-01-06T19:26:25.773 回答
3

在对象==函数中Item,您需要进一步指定如何比较两种类型的字典数组(特别是两种类型的[[Modifications: String]])。

以下工作解决方案item逐个元素比较您的数组(按字典进行字典),并且==仅当数组包含相同数量的字典并且所有条目都相似并且在字典数组中以相同方式排序时才返回 true

func ==(lhs: Item, rhs: Item) -> Bool {

    if lhs.item.count == rhs.item.count {
        for (i, lhsDict) in lhs.item.enumerate() {
            if lhsDict != rhs.item[i] {
                return false
            }
        }
        return true
    }
    else {
        return false
    }
}

class Item : Equatable {

    let item: [[Modifications: String]]

    init(item: [[Modifications: String]]) {
        self.item = item
    }
}

你可能想把它修改成你真正想要用来比较的形式,但我希望你能明白它的要点。

还要注意的是,如果在操场上测试这个,重要的是你的==函数定义func ==(lhs: Item, rhs: Item) -> Bool { ..应该在你的类定义之前,否则你会得到一个不符合Equatable.

于 2016-01-06T19:16:45.777 回答