嗨,我看到了我认为是Scala中奇怪的行为。在bufferedIterator上调用head似乎是在内部函数中增加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

最佳答案

scala.io.Source是且行为类似于Iterator[Char]。因此,您必须确保不要一次在多个地方使用它:Iterator.next在示例中被3种不同的BufferedSource调用了3次,因此得到的值不同:

  • buff1.head:缓冲的源尚未缓冲任何内容,因此,在此处询问head时会调用内部源上的next,因此是第一个a
  • buff1.head再次:这里的头部已经被缓冲,所以您得到a并且内部源没有改变。
  • buffered.head:由于buffereddef,因此等效于source.buffered.head。这个新的缓冲源尚未缓冲任何内容,因此请求head会从内部源中检索元素,因此是b
  • buffered.head:这将创建另一个缓冲源,与上面相同,您会得到c

  • 底线是:如果您调用source.buffered,切勿直接再次使用source,并且不要多次调用

    您可以通过立即调用buffered来修复您的示例:
    val source = Source.fromString("abcdef").buffered
    

    您还可以将def buffered =转换为val buffered =,以确保source.buffered不被多次调用。

    关于scala - 内部函数中的Scala bufferedIterator增量头,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17012067/

    10-10 14:28