为什么 Scala 'String' 对象的迭代器和 'List[Int]' 对象的迭代器在这里表现不同?

Why Scala 'String' object's iterator and 'List[Int]' object's iterator are behaving differently here?

我只是想探索 REPL 中 String 对象和 List[Int] 对象的迭代器的行为,测试如下所示:

scala> val list = List(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
list: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)

scala> val itL = list.iterator
itL: Iterator[Int] = non-empty iterator

scala> List(8,5,list.size-13).map(itL.take(_).mkString)
res85: List[String] = List(12345678, 910111213, 141516)

scala> val st = "abcdefghijklmnop"
st: String = abcdefghijklmnop

scala> val itS = st.iterator
itS: Iterator[Char] = non-empty iterator

scala> List(8,5,st.size-13).map(itS.take(_).mkString)
res84: List[String] = List(abcdefgh, abcde, abc)

为什么迭代器的行为不同?我在 String 对象的情况下的预期输出是:

List[String] = List(abcdefgh, ijklm, nop)

如果可能的话,谁能用例子解释一下。

另一个观察是:Range 对象的迭代器的行为也与 String 对象完全相似 如下所示:

scala> val x = (1 to 16)
x: scala.collection.immutable.Range.Inclusive = Range 1 to 16

scala> val t = (1 to 16).iterator
t: Iterator[Int] = non-empty iterator

scala> List(8,5,x.size-13).map(t.take(_).mkString)
res103: List[String] = List(12345678, 12345, 123)

如果将 Range 转换为 ListSet,则各个迭代器的行为始终完全符合我的预期:

scala> val x1 = (1 to 16).toList
x1: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)

scala> val t1 = x1.iterator
t1: Iterator[Int] = non-empty iterator

scala> List(8,5,x1.size-13).map(t1.take(_).mkString)
res104: List[String] = List(12345678, 910111213, 141516)

scala> val x2 = (1 to 16).toSet
x2: scala.collection.immutable.Set[Int] = Set(5, 10, 14, 1, 6, 9, 13, 2, 12, 7, 3, 16, 11, 8, 4, 15)

scala> val t2 = x2.iterator
t2: Iterator[Int] = non-empty iterator

scala> List(8,5,x2.size-13).map(t2.take(_).mkString)
res105: List[String] = List(51014169132, 12731611, 8415)

Iterator.take(n:Int) API documentation:

附有注释

Reuse: After calling this method, one should discard the iterator it was called on, and use only the iterator that was returned. Using the old iterator is undefined, subject to change, and may result in changes to the new iterator as well.

您似乎发现了一些 "undefined" 行为。