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 and 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]]@ user3441734が正しく言ったように、Foundationフレームワークがインポートされている場合、コードはコンパイルされます。これは、に準拠するものに [String: String]自動的に変換されるためです。その主張の「証拠」は次のとおりです。NSDictionaryEquatable

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は、辞書の 2 種類の配列 (具体的には の 2 種類[[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 に答える