AnyIterator
MyIterator 等價于 AnyIterator,實質是傳入一個生成下一個元素的閉包。
struct MyIterator<Element>:IteratorProtocol {
var base:()->Element?
init(_ body: @escaping () -> Element?) {
base = body
}
func next() -> Element? {
return base()
}
}
var x = 7
let iterator:MyIterator<Int> = MyIterator {
defer { x += 1 }
return x < 15 ? x : nil
}
iterator.next()
這里 x
被關聯至閉包中,充當了數據源的作用,而閉包的作用是操作數據源,這里是生成下一個元素。
接著我們讓 MyIterator 遵循 Sequence
協議,但不用實現任何方法。
extension MyIterator:Sequence {}
var x = 7
let iterator:MyIterator<Int> = MyIterator {
defer { x += 1 }
return x < 15 ? x : nil
}
iterator.next() // 輸出7
for y in iterator {
print(y) // 輸出 8 9 10 11 12 13 14
}
注意 for-in
只要是遵循了 Sequence
,就可以這么用了。本質是調用了 next()
方法。 ps: 注意沒有7哦!
看下蘋果接口的注釋:
/// Every
IteratorProtocol
can also be aSequence
. Note that
/// traversing the sequence consumes the iterator.
extension AnyIterator : Sequence {
}
這么理解:我們的迭代器調用 next()
方法可以一個接一個的生成元素,不就是個序列嗎?但是!這是個一次性消耗品,遍歷一次就消耗殆盡。倘若不信,不妨在前面的代碼之后再調用一次for y in iterator { print(y) }
,啥都沒有吧。
這里有個疑惑:為什么遵循
Sequence
,啥都不用實現呢? 有待考證!
/// To add `Sequence` conformance to your own custom type, add a
/// `makeIterator()` method that returns an iterator.
/// 重點看這里
/// Alternatively, if your type can act as its own iterator, implementing the
/// requirements of the `IteratorProtocol` protocol and declaring conformance
/// to both `Sequence` and `IteratorProtocol` are sufficient.
那底層又是怎么實現的呢?從定義出發
protocol SequenceType {
associatedtype Iterator : IteratorProtocol
func makeIterator() -> Self.Iterator
}
extension SequenceType {
func makeIterator() -> Self.Iterator {
return self as! Self.Iterator
}
}
是不是extension 默認把自己當做 Iterator 返回呢?
AnySequence
Sequence 其實是要關聯一個數據源,姑且稱之為 content
;然后關聯一個生成器iterator
,將 content
中的元素一個個取出。
主要是看 AnySequence
的構造方法
public struct AnySequence<Element> : Sequence {
public init<S : Sequence where S.Iterator.Element == Element, S.SubSequence : Sequence, S.SubSequence.Iterator.Element == Element, S.SubSequence.SubSequence == S.SubSequence>(_ base: S)
public init<I : IteratorProtocol where I.Element == Element>(_ makeUnderlyingIterator: @escaping () -> I)
...
}
暫時沒有想到底層如何實現,有待考證。
IteratorOverOne
這里很好理解,首先初始化一個迭代器,然后用這個迭代器生成一個序列。
func one<A>(x: A) -> AnySequence<A> {
return AnySequence(IteratorOverOne(x))
}
我將定期更新有關此分類的學習筆記。
請關注我的微博:Ninth_Day