嗨,我看到我认为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
答案 0 :(得分:1)
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
。
答案 1 :(得分:1)
在bufferedIterator上调用head似乎是在内部函数中增加头部。
注意:( 2016年7月3年后)
SI-9691
FutureTask.get()
应该公开BufferedIterator
这会向
headOption
特征公开新的API 它将迭代器的下一个元素作为BufferedIterator
返回。如果有下一个值,则返回
Option
;如果没有下一个元素,则返回Some(value)
。
这应该有助于避免任何增量。
答案 2 :(得分:0)
你是对的,除了它不是一个函数,而是一个简单的字段:第66行的IndexedSeqLike,你可以自己使用一些IDE debbuger来检查它并逐步执行