2017-05-08 9 views
0

NodeクラスはSwiftでCollectionを実装しており、各Nodeは同じタイプの子ノードのコレクションとして再帰的に動作します。Swift 3 Collectionサブクラスはコンパイルされません

問題は、私はNodeをサブクラス化するとき、私はまだサブクラスはNodeのコレクションとして機能するようにしたいが、私はそれを訴えて、サブクラスDerivedNodeのインスタンスを反復処理しようとすると、スウィフトもコンパイルされませんです。

IndexingIterator<Node>IndexingIterator<DerivedNode>に変換できません。

なぜこれをやろうとしているのですか?私はDerivedNodeを繰り返し処理しても構いませんが、それらはNodeとして繰り返し処理されます。

興味深いことに、ヘルプのポップアップに正しいタイプが表示されるため、コンパイラ/エディタではタイプがNodeであることがわかります。しかし、それは何らかの理由でコンパイルに失敗します。あなたはイテレータを宣言しない場合は、コレクションはあなたに1つを与える

extension Node: Collection { 
    public typealias Index = Int 

    public var startIndex: Int { 
     return 0 
    } 

    public var endIndex: Int { 
     return attributes.count 
    } 

    public func index(after i: Int) -> Int { 
     return i + 1 
    } 

    public subscript(i: Int) -> Node { 
     return attributes[i].value 
    } 
} 
+0

あなたは 'コレクション'に準拠した方法を示すことができますか? 'Element'として' Node'を使っていますか? –

+0

私は明示的にどこでも 'Element'を宣言していません。私はそれをしなければなりませんか? – devios1

+0

この方法で動作するノードを再作成することはできません。 '属性'とは何ですか? '[Node]'と思われますが、 'value'も' Node'ですか? –

答えて

1

:あなたはしたくない

public func makeIterator() -> IndexingIterator<Self> 

ここ

enter image description here

は私がCollectionプロトコルを実装する方法を説明しますしかし、その1つ。あなたはIndexingIterator<Node>が欲しいです。

public func makeIterator() -> IndexingIterator<Node> { 
    return IndexingIterator(_elements: self) 
} 

これはIndexingIteratorのための文書化されていない初期化子を呼び出す必要があります。だから、あなたはあなた自身のmakeIterator()方法を提供する必要があります。 IMOはbug in the stdlibです。手でIndexingIteratorを作成する必要があります。

+0

ああありがとう!私が読んでいたドキュメンテーションにはその方法は言及されていません。あなたがサブクラス化していないのであれば、技術的には必須ではないと思われますが、間違いなくデフォルトの振る舞いはあなたがいるときにはあまり意味がありません。 – devios1

関連する問題