我可以在Scala 2.10.4中的可变ArrayBuffer上无限循环:
scala> import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.ArrayBuffer
scala> val a = ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9)
a: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9)
scala> val b = a.iterator
b: Iterator[Int] = non-empty iterator
scala> b.take(50).toList
res0: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
scala> b.hasNext
res1: Boolean = true
有什么我不能正确理解的吗?我可以用List做同样的事情并且效果很好。就好像take(nn).toList不会在ArrayBuffer上推进迭代器。
答案 0 :(得分:4)
是的,有些东西你不见了。 take
上Iterator
方法的约定表明在调用该方法后使用迭代器是不安全的。请阅读API文档:
http://www.scala-lang.org/api/2.10.0/index.html#scala.collection.Iterator
take
方法文档声明:
重用:在调用此方法之后,应该丢弃它被调用的迭代器,并仅使用返回的迭代器。使用旧的迭代器是未定义的,可能会发生变化,并且可能导致对新迭代器的更改。
因此,使用额外的变量来捕获take
的结果会产生您的预期:
scala> import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.ArrayBuffer
scala> val a = ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9)
a: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9)
scala> val b = a.iterator
b: Iterator[Int] = non-empty iterator
scala> val c = b.take(50)
c: Iterator[Int] = non-empty iterator
scala> c.toList
res0: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
scala> c.hasNext
res1: Boolean = false