我正在尝试编写自己的IndexingIterator
版本,以增加对Sequence
的理解。我没有在我的struct中为associatetype Iterator指定任何类型。但是,编译器没有抱怨这一点,我得到了makeIterator
的默认实现。
以下是我的代码:
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 :(得分:1)
看起来亚历山大的回答是正确的。这是一个简化版本,不使用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()
答案 1 :(得分:0)
类型别名不是必需的,因为Element
关联类型是从next()
的实现中推断出来的。
这是一个简单的例子:
protocol ResourceProvider {
associatedtype Resoruce
func provide() -> Resoruce;
}
struct StringProvider {
func provide() -> String { // "Resource" inferred to be "String"
return "A string"
}
}
答案 2 :(得分:0)
您可以先编写自己的Iterator,然后将其与IteratorProtocol
对话,然后将您需要的内容写入Sequence
。
确保您必须实施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)
}
}