2013-05-03 13 views
6

私は次のコードを実行しています:スカラ - イテレータとtakeWhile

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)となっています。これはなぜですか? headtakeWhileを呼び出して評価され、結果は同じになるはずですか?

答えて

15

イテレータは可変であるため、it.headの値は評価時点によって異なります。

implementation of takeWhileを調べると、の先頭が削除され、の述語が適用されることがわかります。

したがって、3番目の要素が既に削除されているため、述語内から評価されたit.head2になります。

これは、不変性を好む理由の説明です。それは、このような非自明な行動の全クラスを排除する。

0

上記の@Ben Jamesの回答に追加してください。値は、2行目の後に第3の反復で

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

hd=1とイテレータ残りはList(2,2,3,3)ある以下takeWhile方法コード(:ベンクレジット)です。 p(hd)を呼び出すと、イテレータのhead(この場合は2)をチェックします。したがって、それは壊れます。