2016-11-18 22 views
4

我想写我自己的IndexingIterator版本来增加我对Sequence的理解。我没有在我的结构中分配任何类型到associatetype Iterator。然而,编译器并没有抱怨,我得到了makeIterator的默认实现。符合Swift中的Sequence和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',但是'Sequence'中的关联类型'Iterator'不能被推断,因为我的'__IndexingIterator'定义没有'Iterator'的类型分配。我需要一个解释。 – Evan

+0

您展示的扩展(第二个最后的代码片段)为序列和集成器的类型定义了默认实现。这个扩展默认是这样的,这种类型通过返回自己的'makeIterator()'符合'Sequence'。 '__IndexingIterator'符合标准,因为它既是一个序列又是一个迭代器。因此它获得了'makeIterator'的这个默认实现。这个默认的实现返回一个'Self'类型,它在这个上下文中解析为'__IndexingIterator'。 – Alexander

+0

编译器也知道'makeIterator'的返回类型是关联类型'Iterator',所以它将2和2放在一起得出结论'Iterator'是'__IndexingIterator' – 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

您可以编写自己的迭代器,其confrom到IteratorProtocol第一,然后写你需要什么confrom到Sequence

请确保您必须实施requried功能。

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) 
     } 
    }