Scala Iterator下一个方法缓存结果?

时间:2017-04-04 21:42:18

标签: scala iterator

我遇到此代码的问题:

case class MyIterator(myVal: Int) extends Iterator[MyIterator] {
    override def hasNext:Boolean = true
    override def next(): MyIterator = MyIterator(myVal+1)
    override def toString:String = s"MyIterator : $myVal"
}

object Main extends App {
    val mi = new MyIterator(0)
    mi.take(5).foreach(println(_))
}

我希望看到的是:

MyIterator : 0
MyIterator : 1
MyIterator : 2
MyIterator : 3
MyIterator : 4

但我得到了:

MyIterator : 1
MyIterator : 1
MyIterator : 1
MyIterator : 1
MyIterator : 1

我真的不明白为什么。有人知道发生了什么吗?

1 个答案:

答案 0 :(得分:2)

如果查看take的来源,您会看到它调用方法slice,如下所示:

def slice(from: Int, until: Int): Iterator[A] = {
  val lo = from max 0
  var toDrop = lo
  while (toDrop > 0 && self.hasNext) {
    self.next()
    toDrop -= 1
  }

  new AbstractIterator[A] {
    private var remaining = until - lo
    def hasNext = remaining > 0 && self.hasNext
    def next(): A =
      if (remaining > 0) {
        remaining -= 1
        self.next()
      }
      else empty.next()
  }
}

在迭代器上的while循环next被重复调用,即下一次迭代它不会在你返回的迭代器上调用next,而是继续调用{{1}在同一个实例上。你创建的本质上是一个迭代器,它总是会返回一个新的next,但每次都会返回相同的值。

您是否有特定原因希望以递归方式实现它?迭代器本身需要某种状态来跟踪从特征写入方式返回的值。似乎很难以其他类期望它们工作的方式不可变地实现它们。如果这就是你所追求的,请改为MyIterator