关于迭代器的理解

关于迭代器的理解

B05高端研讨会第一期
时间:12月21日。
与会:professor yang、always hurry、old fake

正文

迭代器应该是我们在编程中使用的最多的设计模式,但是我们因为常见而常常忽略她的存在,我们就来探究一下一行foreach语句背后所蕴含的道理。

起点:遍历容器

在没有迭代器的时候,我们想遍历一个容器里的内容应该怎么办?如果是一个数组,我们只需要累加索引然后依次访问就可以了。对于链表我们要拿到第一个元素,然后再通过第一个元素拿到下一个元素,依次往下,直到最后一个元素。如果我们往下想,那么所有的容器都需要有一个单独对应的遍历方法,这显然是不合理的,设计第一步就是要把可以独立的概念抽离出来,那么遍历一个容器行为,就是需要我们抽离的概念。

迭代器的意义

迭代器的意义就在于 在不暴露一个容器内部表示的情况下,顺序遍历一个容器。

迭代器的具象

在军训中 我们都站过队列,报过数,我把报数这个行为,作为迭代器的具象。想象一下 如果教官需要知道当前军训的有多少人,我们只要挨个报数就行了,每一个军训的学员 只要知道 我自己是谁, 下一个是谁,当最后一个学员报完的时候,遍历军训学员 这个容器的操作 就算完成了。无论军训学员站成几排几列,站成圆形还是方形,只要每一个学员知道自己是谁,下一个是谁,都可以完成这个操作。

迭代器模式的实现

在C#中我们可以找到 跟军训学员对应的实现,


    public interface IEnumerator
    {
        object Current { get; }

        bool MoveNext();
        void Reset();
    }

对于 Current 属性,就是表示当前报数的这个学员是谁,MoveNext 就是要知道我下一个有没有人,如果有人就把报数的顺序交给她。
在C#中,所有的容器,都实现了这个借口,所以我们才能使用foreach遍历。

迭代器中的角色

我们说要把遍历一个容器的行为抽象出来,仅仅是容器实现了对应的接口,明显还不够,因为我们缺角色。其实上例中提到的IEnumerator 接口,准确的定位应该是迭代器工厂,用于生产迭代器对象的。
当迭代器对象被生产出来,还需要另一个角色来唤醒她,这个角色就是迭代者,就像我们在军训时的教官一样,负责宣布开始,叫停。
在C#中,foreach就是迭代者的角色。
我们分析一下以下语句:

Dictionary<int, int> dic = new Dictionary<int, int>();
 foreach (var item in dic)
        {

        }

这个语法中,有dic这个容器提供迭代器对象,由foreach语句不停地访问当前的对象,并且让当前的迭代器对象执行MoveNext 操作。

在Lua中的实现

在Lua中也有迭代器的实现,迭代器工厂是ipairs、pairs,迭代者是for语句。由于Lua是弱类型的语言,所以没有明确的迭代器的类型定义,但是只要符合了她的标准的方法,都可以作为迭代器工厂使用。
下面是我用closure实现的一个最简单的迭代器模式:
在这里插入图片描述

总结

以下是我们讨论总结的思维导图。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值