2016-11-18 5 views
4

私はIndexingIteratorという自分のバージョンを書いて、Sequenceを理解しています。私は私の構造体でassociatetype Iteratorに型を割り当てていません。しかし、コンパイラはそれについて不平を言っておらず、私はmakeIteratorのデフォルト実装を得ています。続きSwiftのSequence and IteratorProtocolに準拠

は私のコードです:

struct __IndexingIterator<Elements: IndexableBase>: Sequence, IteratorProtocol { 
    mutating func next() -> Elements._Element? { 
     return nil 
    } 
} 
let iterator = __IndexingIterator<[String]>() 
// this works and returns an instance of __IndexingIterator<Array<String>>. why? 
iterator.makeIterator() 

私は、デフォルトの実装を追加Sequence上のいくつかの拡張機能がなければならないと思います。したがって、私はSequence.swiftでそれを検索し、これだけが見つかりました。

extension Sequence where Self.Iterator == Self, Self : IteratorProtocol { 
    /// Returns an iterator over the elements of this sequence. 
    public func makeIterator() -> Self { 
    return self 
    } 
} 

私はそれがこのようなことだろうと思った:

extension Sequence where Self: IteratorProtocol { 
    typealias Iterator = Self 
    ... 
} 

は、私が何かを逃したのか、私は拡張子を誤解しましたか?

+0

誰でも手助けできます。 – Evan

答えて

0

Elementに関連付けられたタイプがnext()の実装から推測されるため、タイプエイリアスは必要ありません。アレキサンダーの答えが正しいかのように見えます

protocol ResourceProvider { 
    associatedtype Resoruce 
    func provide() -> Resoruce; 
} 

struct StringProvider { 
    func provide() -> String { // "Resource" inferred to be "String" 
     return "A string" 
    } 
} 
+0

私はあなたの意見に同意しますが、私の問題を説明することはできません。 IteratorProtocolの関連タイプ 'Element'は' _IndexableBase._Element'と推測できますが、 '__IndexingIterator'の定義に' Iterator'の型割り当てがないので、 'Sequence'の関連タイプ' Iterator'は推論できません。そして私はそれについて説明する必要があります。 – Evan

+0

あなたが示したその拡張子(2番目の最後のコードスニペット)は、シーケンスとインテグレータの両方であるタイプのデフォルト実装を定義しています。この拡張は、デフォルトでは 'makeIterator()'の戻り値そのものによって 'Sequence'に適合します。 '__IndexingIterator'は、シーケンスとイテレータの両方のために基準に合っています。その結果、 'makeIterator'のこのデフォルト実装が得られます。このデフォルトの実装は 'Self'型を返します。この型は' __IndexingIterator'に解決されます。 – Alexander

+0

コンパイラは、 'makeIterator'の戻り値の型が' Iterator'型であることも知っています。したがって、 'Iterator'が' __IndexingIterator'であると結論づけるために2と2を一緒に入れています – Alexander

0

:ここ

は簡単な例です。ここでSequenceを使用せずに、煮詰めたバージョンです:

protocol MySequence { 
    associatedtype Iterator: IteratorProtocol 
    func maakeIterator() -> Iterator 
} 

extension MySequence where Self.Iterator == Self, Self : IteratorProtocol { 
    /// Returns an iterator over the elements of this sequence. 
    func maakeIterator() -> Self { 
     return self 
    } 
} 

struct __IndexingIterator<Element>: MySequence, IteratorProtocol { 
    mutating func next() -> Element? { 
     return nil 
    } 
} 

let iterator = __IndexingIterator<[String]>() 
iterator.maakeIterator() 
0

はあなたがIteratorProtocol最初にconfrom独自のIteratorを書くことができ、その後、あなたはSequenceにconfromを必要とするものを書きます。

requried funcを実装する必要があることを確認してください。

struct IteratorTest : IteratorProtocol { 
     typealias Element = Int 

     var count : Int 

     init(count :Int) { 
      self.count = count 
     } 

     mutating func next() -> Int? { 
      if count == 0 { 
       return nil 
      }else { 
       defer { 
        count -= 1 
       } 
       return count; 
      } 
     } 
    } 

    struct CountDown : Sequence { 
     typealias Iterator = IteratorTest 
     func makeIterator() -> IteratorTest { 
      return IteratorTest.init(count: 10) 
     } 
    } 
関連する問題