2013-03-19 13 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方法,這也有相當明確的文件,說明不使用迭代器:

重用:調用此方法後,應該放棄它被調用的迭代器,並且只使用返回的迭代器。使用舊的迭代器是未定義的,可能會有變化,並且可能導致新迭代器的更改。

斯卡拉一般旨在成爲一種「實用」語言 - 突變和副作用允許出於性能和互操作性的原因,儘管不鼓勵。然而,將它稱爲「隱藏的」是有一點延伸的。

相關問題