第三篇:AnyIterator , AnySequence ,IteratorOverOne的补充解释

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 11,220评论 6 13
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,067评论 19 139
  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young阅读 3,923评论 1 10
  • begin with one quickSort 之前在学习时曾看到swift如此简洁地表达出了快排算法。 时虽叹...
    KisugiRui阅读 1,574评论 0 2
  • 上午看到有朋友在微社吆喝,发上照片,请求大家帮她挑选眼镜。看到这些,第一反应是,自己的审美眼光不行,比较僵化保守,...
    绽蕊向阳阅读 206评论 0 0