Двоичный оператор '==' не может применяться к двум операндам

У меня есть класс с протоколом 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]], и проблем не было, и я не знаю, как это исправить. Я пробовал искать и искать по всему, но не повезло..

Перечисление просто простое:

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

Ответ 1

Проблема в том, что даже если == определен для типа словаря [Modifications: String], этот тип не соответствует Equatable. Поэтому оператор сравнения массива

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

нельзя применить к [[Modifications: String]].

Возможная краткая реализация == для Item будет

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

Ваш код компилируется для [[String: String]] - если Фонд framework импортируется, так как @user3441734 правильно сказал - потому что тогда [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]]() )

Ответ 2

В вашей функции == для объектов Item вам нужно дополнительно указать, как сравнить два типа массивов словарей (в частности, два типа [[Modifications: String]]).

Следующее рабочее решение сравнивает ваш элемент Item массивов по элементу (словарь по словарю), а == возвращает true, только если массивы содержат одинаковое количество словарей, и если все записи одинаковы и упорядочены одинаково в массиве dictionares

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.