2013-03-19 76 views
2

对我来说,这真是一个惊喜(行< - 线)是如此毁灭性的!它完全解开了行迭代器。因此,运行下面的代码片断将让大小= 0:为什么在迭代它之后`Source.fromFile(...)。getLines()`是空的?

val lines = Source.fromFile(args(0)).getLines() 
    var cnt = 0 
    for (line <- lines) { 
    cnt = readLines(line, cnt) 
    } 
    val size = lines.size 

它是一个正常的Scala的做法有很好的隐蔽性的副作用也是这样吗?

+0

[为什么我的Scala列表在以下代码中消失?](http://stackoverflow.com/questions/7138671/why-does-my-scala-list-disappear-in-the-follow-码) – 2013-03-19 16:04:03

回答

5

Source.getLines()返回一个迭代器。对于每个迭代器,如果您调用上述的foreachmap,take,toList等批量操作,则迭代器不再处于可用状态。 这是Iterators的合同,更一般地说,是继承TraversableOnce的类。

特别重要的是要注意,除非另有说明,否则在调用方法之后不应该使用迭代器。两个最重要的例外也是唯一的抽象方法:next和hasNext。

对于继承Traversable的类,情况并非如此,您可以随意调用批量遍历操作。

3

Source.getLines()返回Iterator,并且步行穿过Iterator将使其变异。这在Scala documentation中很清楚

迭代器是可变的:对它的大多数操作都会改变它的状态。虽然它经常用于迭代集合的元素,但也可以在不受任何集合支持的情况下使用它(请参阅伴随对象上的构造函数)。

特别重要的是要注意,除非另有说明,否则在调用方法后不应使用迭代器。两个最重要的例外也是唯一的抽象方法:next和hasNext。

使用for符号只是语法糖呼吁迭代mapflatMapforeach方法,这也有相当明确的文件,说明不使用迭代器:

重用:调用此方法后,应该放弃它被调用的迭代器,并且只使用返回的迭代器。使用旧的迭代器是未定义的,可能会有变化,并且可能导致新迭代器的更改。

斯卡拉一般旨在成为一种“实用”语言 - 突变和副作用允许出于性能和互操作性的原因,尽管不鼓励。然而,将它称为“隐藏的”是有一点延伸的。

相关问题