我正在运行以下代码:
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
,结果应该相同吗?
答案 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
。因此它会破裂。