我是靠谱客的博主 故意外套,最近开发中收集的这篇文章主要介绍如何写一个正确的iterator,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

我们知道, iterator 是一个可变对象, 换句话来说, 它的next方法是有副作用的。
 对于那些由容器产生的iterator来说, hasNext一般都是没有副作用的。但是, 某些时候, hasNext也是可能有副作用的。举个例子来说, 如果我们要基于BufferedReader来写一个可以迭代行的迭代器, 我们就要在hashNext里面尝试读取新的一行, 于是, 副作用就产生了。 

当我们的hasNext方法是有副作用的时候, 就要特别小心了。因为用户有可能会连续多次调用hasNext这个方法!

同时,我们还要考虑一个问题。 一般情况下, 我们理想的迭代器使用方法是这样的

if (iter.hasNext) { val v = iter.next; 使用v来做一些事情 } else {退出迭代过程}
if (iter.hasNext) { val v = iter.next; 使用v来做一些事情 } else {退出迭代过程}
if (iter.hasNext) { val v = iter.next; 使用v来做一些事情 } else {退出迭代过程}

......


也就是说, 我们的迭代器的正确性依赖于 hasNext, next, hasNext, next....这个“合理的”调用序列
但是, 事实上, 用户其实并不一定会按照这种正确的调用顺序来使用我们的迭代器。

为了实现一个可以让用户随意安排调用序列, 我们要让迭代器满足两个性质:
1。任何时候, 任意两次连续的hasNext方法, 总是等价于一次hasNext
2。任何时候, 任意两次连续的next方法, 都等价于在这两个next方法中间插入一个hasNext方法

所谓的“a等价于b”, 就是说, 无论是通过途径a还是途径b, iterator最后的内部状态 都是一样的。

 只要同时满足这两个性质, 就可以放心地把iterator的正确性 设计成 依赖于 hasNext, next, hasNext, next....这个“合理的”调用序列 。


可以发现, 对于基于容器(List,Map,Set等等)的iterator来说, 这两个性质是“天然地, 直接地, 简单地”就满足的。其原因在于:如果hasNext方法是无副作用的,那么上面的两个性质一定会满足

但是当我们要写一些并不是基于容器的迭代器的时候, 这时候hasNext方法有可能会有副作用, 我们就要注意检查是否满足上面两个条件了。


总结起来:

当作为iterator的编写者的时候: 我们要尽量让hasNext没有副作用,如果实在不行,就要注意验证是不是能够满足上面的两个性质. 

当作为iterator的使用者的时候: 我们要假定hasNext是有副作用的, 所以要严格按照hasNext, next ... 这个调用序列来使用别人写的iterator


最后,给出一个例子, 写一个可以迭代行的迭代器:


import java.io._

def toReader(fp: String, enc: String): Reader = new InputStreamReader(new FileInputStream(new File(fp)), enc)

def iLines(reader: Reader): Iterator[String] = {
    val br = new BufferedReader(reader)

    var curline = ""

    var checked = false
    var checkedRes = false

    new Iterator[String] {
        def hasNext: Boolean = {
            if (checked) return checkedRes
            
            checked = true
            curline = br.readLine()
            checkedRes = if (curline != null) true else false
            return checkedRes
        }

        def next: String = {
            if (!checked) this.hasNext
            
            checked = false
            return curline
        }
    }

} 

转载于:https://my.oschina.net/mustang/blog/91547

最后

以上就是故意外套为你收集整理的如何写一个正确的iterator的全部内容,希望文章能够帮你解决如何写一个正确的iterator所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(68)

评论列表共有 0 条评论

立即
投稿
返回
顶部