为什么这个 Iterator 会无限循环?
Why does this Iterator infinitely loop?
我正在尝试链接 Iterators
:
var it = Iterator(1)
it.next
it = Iterator(2) ++ it
it.next
it.hasNext
这会在 hasNext
上无限循环,如您在此处所见:https://scastie.scala-lang.org/qbHIVfsFSNO5OYmT4pkutA
如果你 运行 在它无限循环的同时检查堆栈,它正在循环中:
at scala.collection.Iterator$ConcatIterator.merge(Iterator.scala:213)
at scala.collection.Iterator$ConcatIterator.advance(Iterator.scala:197)
at scala.collection.Iterator$ConcatIterator.hasNext(Iterator.scala:227)
(此堆栈来自 Scala 2.12.11
,但 Scastie link 在 2.13.2
中显示相同的行为)。
我知道 在其上调用方法后永远不应该使用迭代器,但这似乎对我有用。使用 var
指向 "current" 迭代器并将其更改为指向一个新的迭代器,该迭代器附加前一个迭代器的剩余部分。
以下轻微修改确实有效:
var it = Iterator(1)
it.next
val x = it
it = Iterator(2) ++ x
it.next
it.hasNext
斯卡斯蒂 link: https://scastie.scala-lang.org/1X0jslb8T3WIFLHamspYAg
这向我表明,损坏的版本以某种方式创建了一个附加自身的迭代器。关于这里发生了什么的任何提示?
Iterator
的 ++
方法的参数按名称传递。 ++
returns 一个新的 Iterator
,它只存储一个 returns it
的函数,但在您尝试使用附加元素之前不会调用它。
所以 ++
仅在您调用 it.hasNext
时尝试计算参数,但到那时 it
已经被重新定义为 ++
的结果,因此它最终尝试将 it
附加到自身。
换句话说,var
s 和别名参数不能一起使用。
所以不要将 Iterator
方法结果重新分配给同一个变量,而是给它们新的名称:
val it = Iterator(1)
it.next
val it2 = Iterator(2) ++ it
it2.next
it2.hasNext
我正在尝试链接 Iterators
:
var it = Iterator(1)
it.next
it = Iterator(2) ++ it
it.next
it.hasNext
这会在 hasNext
上无限循环,如您在此处所见:https://scastie.scala-lang.org/qbHIVfsFSNO5OYmT4pkutA
如果你 运行 在它无限循环的同时检查堆栈,它正在循环中:
at scala.collection.Iterator$ConcatIterator.merge(Iterator.scala:213)
at scala.collection.Iterator$ConcatIterator.advance(Iterator.scala:197)
at scala.collection.Iterator$ConcatIterator.hasNext(Iterator.scala:227)
(此堆栈来自 Scala 2.12.11
,但 Scastie link 在 2.13.2
中显示相同的行为)。
我知道 在其上调用方法后永远不应该使用迭代器,但这似乎对我有用。使用 var
指向 "current" 迭代器并将其更改为指向一个新的迭代器,该迭代器附加前一个迭代器的剩余部分。
以下轻微修改确实有效:
var it = Iterator(1)
it.next
val x = it
it = Iterator(2) ++ x
it.next
it.hasNext
斯卡斯蒂 link: https://scastie.scala-lang.org/1X0jslb8T3WIFLHamspYAg
这向我表明,损坏的版本以某种方式创建了一个附加自身的迭代器。关于这里发生了什么的任何提示?
Iterator
的 ++
方法的参数按名称传递。 ++
returns 一个新的 Iterator
,它只存储一个 returns it
的函数,但在您尝试使用附加元素之前不会调用它。
所以 ++
仅在您调用 it.hasNext
时尝试计算参数,但到那时 it
已经被重新定义为 ++
的结果,因此它最终尝试将 it
附加到自身。
换句话说,var
s 和别名参数不能一起使用。
所以不要将 Iterator
方法结果重新分配给同一个变量,而是给它们新的名称:
val it = Iterator(1)
it.next
val it2 = Iterator(2) ++ it
it2.next
it2.hasNext