嗨,我看到了我认为是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
:由于buffered
是def
,因此等效于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/