为什么 Scala 'String' 对象的迭代器和 'List[Int]' 对象的迭代器在这里表现不同? [英] Why Scala 'String' object's iterator and 'List[Int]' object's iterator are behaving differently here?

查看:38
本文介绍了为什么 Scala 'String' 对象的迭代器和 'List[Int]' 对象的迭代器在这里表现不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是想探索 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 转换为 ListSet,则相应的迭代器的行为始终完全符合我的预期:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆