2015-10-17 16 views
12

SetをHashableプロトコルとカスタムプロトコルに対応する値で初期化したいとします。Swiftでの設定とプロトコル

は、私が試した:

protocol CustomProtocol: Hashable {} 

let set = Set<CustomProtocol>() 

しかし、Xcodeは文句:

が 'ハッシュ可能' は

どう

がサポートされていないプロトコルに準拠した具体的なタイプとして 'CustomProtocol' をすることができます使用します私はそれを達成する?

ありがとうございます。

+0

のオブジェクトは既にHashableに準拠する必要があります。 – Abizern

+0

CustomProtocolがHashableに準拠していない場合、Xcodeはそれに準拠していないCustomProtocolについて不平を言っています。私は何かが欠けているように見えます。 –

答えて

8

あなたがしたいことをやり遂げることができない直接の理由は、Hashableが汎用プロトコルであることです。したがって、それまたはそれから派生したプロトコルはSetの要素型として使用できません。ジェネリック型は、別のジェネリックの制約としてのみ使用できます。セットの要素タイプがである必要がありますが、をHashableに準拠させる必要がある場合でも、Set<Hashable>を宣言することはできません。

最も簡単な方法は、プロトコルのセットではなく、オブジェクトタイプのセットを作成することです。 Sは(それがハッシュ可能に準拠プラス任意の他CustomProtocolが伴うため)CustomProtocolに準拠した構造体である場合たとえば、あなたはS.のセット

例宣言することができます。

protocol CustomProtocol: Hashable { 

} 

func ==(lhs:S,rhs:S) -> Bool { 
    return lhs.name == rhs.name 
} 

struct S : CustomProtocol { 
    var name : String 
    var hashValue : Int { return name.hashValue } 
} 

let set = Set<S>() 

た場合の問題、あなたにもかかわらず、何らかの形で相互に同等である混合型のコレクションを望むなら、それはプロトコル指向のWWDC 2015ビデオの議論で説明されているように、プロトコル拡張によって解決される同じ問題です。

しかし、NSObjectから派生したすべての型クラスを作成する方が簡単です。もちろん、それらにはいくつかのセカンダリプロトコルを採用させることはできますが、そのセットはそのプロトコルのセットではなくNSObjectのセットとして定義されます。

+0

ありがとうございます。しかし、私は別のクラスからの私の設定されたオブジェクトに挿入したい、一つではない。だからこそ私は "プロトコルのセット"を作ることを望んでいません。 –

+0

改訂版の回答を参照してください。 – matt

+0

あなたが既にアドバイスされているように、すべてのクラスをNSObjectから派生させるのが最も簡単な方法です。 – matt

1

スウィフト3では、1つの解決策はAnyHashable structureを使用することです。例えば

、オブザーバー/ observableパターンを作成するために、我々は行うことができます:私は私のプロトコルObserverからHashableプロトコルを分離

protocol Observer { 
    func observableDidSomething(_ observable: Observable) 
} 

class Observable { 
    private var observersSet: Set<AnyHashable> = [] 

    private var observers: [Observer] { 
     return observersSet.flatMap { $0 as? Observer } 
    } 

    func add<O>(_ observer: O) where O : Observer, O : Hashable { 
     observersSet.insert(observer) 
    } 

    func remove<O>(_ observer: O) where O : Observer, O : Hashable { 
     observersSet.remove(observer) 
    } 

    // ... 

    private func doSomething() { 
     // do something ... 
     observers.forEach { $0.observableDidSomething(self) } 
    } 
} 

お知らせ。

関連する問題