美文网首页
第三篇:AnyIterator , AnySequence ,I

第三篇:AnyIterator , AnySequence ,I

作者: NinthDay | 来源:发表于2017-02-28 21:45 被阅读424次

    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 a Sequence. 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

    相关文章

      网友评论

          本文标题:第三篇:AnyIterator , AnySequence ,I

          本文链接:https://www.haomeiwen.com/subject/mgyfgttx.html