Scala - 迭代器和takeWhile

时间:2013-05-03 10:35:20

标签: scala iterator

我正在运行以下代码:

 val it = List(1,1,1,2,2,3,3).iterator.buffered
 val compare = it.head
it.takeWhile(_ == compare).toList

并返回(1,1,1)。但是,如果我将其作为:

运行
val it = List(1,1,1,2,2,3,3).iterator.buffered
it.takeWhile(_ == it.head).toList

我得到(1,1)。为什么会这样?在调用head时评估不是takeWhile,结果应该相同吗?

2 个答案:

答案 0 :(得分:16)

因为迭代器是可变的,it.head的值取决于它的评估时间。

检查implementation of takeWhile显示它在应用谓词之前删除了迭代器的头部。

因此,在第三次迭代中,从谓词中评估的it.head将为2,因为第三个元素已被删除。

这说明了为什么你更喜欢不变性。它排除了一类非显而易见的行为。

答案 1 :(得分:0)

添加@Ben James回答上面的问题。以下是takeWhile方法代码(credit:ben):

def hasNext = hdDefined || tail.hasNext && {
  hd = tail.next() //line 2
  if (p(hd)) hdDefined = true
  else tail = Iterator.empty
  hdDefined
}

在第2行之后的第三次迭代中,值为:hd=1,剩余的Iterator为List(2,2,3,3)。在调用p(hd)时,它会检查迭代器的head,在这种情况下是2。因此它会破裂。