为什么 Scala 'String' 对象的迭代器和 'List[Int]' 对象的迭代器在这里表现不同? [英] Why Scala 'String' object's iterator and 'List[Int]' object's iterator are behaving differently here?
问题描述
我只是想探索 REPL 中 String
对象和 List[Int]
对象的迭代器的行为,测试如下所示:>
I just wanted to explore the behaviors of the iterators of a String
object and a List[Int]
object in REPL and the tests are as shown below:
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
对象的情况下的预期输出是:
Why the iterators are behaving differently? My expected output in String
object's case is:
List[String] = List(abcdefgh, ijklm, nop)
如果可能的话,有人可以用例子解释这一点.
Can somebody explain this if possible with examples.
另一个观察是:Range
对象的迭代器的行为也和String
对象完全相似如下所示:
Another Observation is: The behaviour of the iterator of the Range
object is also exactly similar to String
object
as seen below:
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
转换为 List
或 Set
,则相应的迭代器的行为始终完全符合我的预期:强>
If the Range
is converted to List
or Set
the respective iterators are behaving exactly as per my expectation always:
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 文档:
重用:调用此方法后,应丢弃调用它的迭代器,只使用返回的迭代器.使用旧迭代器是未定义的,可能会发生变化,并且也可能导致对新迭代器的更改.
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.
您似乎发现了一些未定义"的行为.
It looks like you've discovered some "undefined" behavior.
这篇关于为什么 Scala 'String' 对象的迭代器和 'List[Int]' 对象的迭代器在这里表现不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!