2016-04-24 14 views
4

最後の式の評価中にREPLがスタックされている理由は誰にもありませんか?奇妙なことは、何も例外も何も投げていないということです。何も起こりません。Iterator.continually:Scalaで式を評価できませんREPL

Welcome to Scala version 2.11.6 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_40). 

scala> val empty = Seq.empty[Int].iterator 
empty: Iterator[Int] = empty iterator 

scala> val emptyInfiniteIterator = Iterator.continually(empty).flatten 

ありがとうございました。

答えて

5

ここでは何が起こりますか。あなたはScalaのREPLでイテレータを定義すると、そのイテレータに関するいくつかの情報は、それが特に空かないのかどうか、印刷されています

この情報は、次のように定義されて IteratortoString方法によって返され
scala> Iterator.continually(List(1)).flatten 
res1: Iterator[Int] = non-empty iterator 

override def toString = (if (hasNext) "non-empty" else "empty")+" iterator" 

基本的には、hasNextが新しく作成されたイテレータで呼び出されます。今度はhasNextは、あなたのケース(scala.collection.TraversableOnce.FlattenOps#flatten)に何をするか見てみましょう:

class FlattenOps[A](travs: TraversableOnce[TraversableOnce[A]]) { 
    def flatten: Iterator[A] = new AbstractIterator[A] { 
     val its = travs.toIterator 
     private var it: Iterator[A] = Iterator.empty 
     def hasNext: Boolean = it.hasNext || its.hasNext && { it = its.next().toIterator; hasNext } 
     def next(): A = if (hasNext) it.next() else Iterator.empty.next() 
    } 
    } 

なるほど! hasNextは、反復的に反復子を走査して、空でない要素が1つも見つからないようにします。あなたの場合、空の要素の無限反復子があるので、決して起こることはありません。ですから、あなたはREPLによって引き起こされる無限ループを持っています。テール再帰が使用され、スカラではwhileループに移行されるので、StackOverflowは得られません。

+0

いいです。 '(1〜10).iterator span(_ <5)'のように 'toString'をオーバーライドする必要があります。 –

+0

@ som-snytt、 'toString'を指摘してくれてありがとう、何らかの理由で、REPLがかなりの値を印刷するために何か他のものを使っていると想像しました。おそらく、私は[アンモナイト](http://www.lihaoyi.com/Ammonite/#Ammonite-REPL)を念頭に置いていましたが、これは標準タイプに 'toString'を使用していません。とにかく、すべての部分がその場にあります。 – Aivean

+0

違う方法で 'toString'をオーバーライドしたとしても、イテレータを何かのために使用しようとしたときに、同じ無限ループを繰り返します... OPが作成したものは、無限ループが起こるのを待っています。 「平らな」とはどういう意味ですか? –

関連する問題