Scala bufferedIterator在内部函数中递增头部

时间:2013-06-09 17:07:18

标签: scala

嗨,我看到我认为scala中的奇怪行为。在bufferedIterator上调用head似乎是在内部函数中增加头部。要么我的考虑是错误的,在哪种情况下输出是正确的。或者输出错了?

下式给出:

import scala.io.Source

val source = Source.fromString("abcdef")

val buff1 = source.buffered;

println("outer head 1: " +buff1.head)
println("outer head 2: " +buff1.head)

def readLine():List[String] = {
  def buffered = source.buffered
  def readLine(tokens:List[String] , partialToken:String):List[String] = {
    println("head1 " + buffered.head)
    println("head2 " + buffered.head)
    return Nil;
  }
  return (readLine(Nil, ""));
}

readLine();

这对我的预期输出是

outer head 1: a
outer head 2: a
head1: a
head2: a

实际输出如下。

outer head 1: a
outer head 2: a
head1 b
head2 c

3 个答案:

答案 0 :(得分:1)

scala.io.Source的行为与Iterator[Char]相似。因此,您必须确保不要在多个位置同时使用它:Iterator.next在您的示例中从3个不同的BufferedSource调用3次,因此您获得的值不同:

  1. buff1.head:缓冲的来源尚未缓冲任何内容,因此请求head在此处调用内部源next,因此第一个a
  2. 再次
  3. buff1.head:此处已经缓冲了头部,因此您获得了a并且内部源未被更改。
  4. buffered.head:由于buffereddef,因此相当于source.buffered.head。这个新的缓冲源还没有缓冲任何东西,所以要求head从内部源检索一个元素,因此b
  5. buffered.head:这会创建另一个缓冲来源,与上面相同,您获得c
  6. 最重要的是:如果您致电source.buffered,则不要再直接使用source,也不要多次调用

    您的示例可以立即致电buffered来修复:

    val source = Source.fromString("abcdef").buffered
    

    您也可以将def buffered =变为val buffered =,以确保多次调用source.buffered

答案 1 :(得分:1)

  

在bufferedIterator上调用head似乎是在内部函数中增加头部。

注意:( 2016年7月3年后)

Commit 11688eb显示:

  

SI-9691 FutureTask.get()应该公开BufferedIterator

     

这会向headOption特征公开新的API   它将迭代器的下一个元素作为BufferedIterator返回。

     

如果有下一个值,则返回Option;如果没有下一个元素,则返回Some(value)

这应该有助于避免任何增量。

答案 2 :(得分:0)

你是对的,除了它不是一个函数,而是一个简单的字段:第66行的IndexedSeqLike,你可以自己使用一些IDE debbuger来检查它并逐步执行