Luigi Plinge
Luigi Plinge

Reputation: 51109

Unexpected behaviour of iterator on String

Can anyone explain why these iterators behave differently? I generally expect a String to act like an IndexedSeq[Char]. Is this documented anywhere?

val si: Iterator[Char] = "uvwxyz".iterator
val vi: Iterator[Char] = "uvwxyz".toIndexedSeq.iterator

val sr = for (i <- 1 to 3) 
           yield si take 2 mkString
  //sr: scala.collection.immutable.IndexedSeq[String] = Vector(uv, uv, uv)

val vr = for (i <- 1 to 3) 
           yield vi take 2 mkString
  //vr: scala.collection.immutable.IndexedSeq[String] = Vector(uv, wx, yz)

Upvotes: 7

Views: 291

Answers (1)

Moritz
Moritz

Reputation: 14212

There are no guarantees about the state of the iterator after you invoke take on it.

The problem with iterators is that many useful operations can only be implemented by causing side effects. All these operations have a specified direct effect but may also have side effects that cannot be specified (or would complicate the implementation).

In the case of take there are implementations that clone the internal state of the iterator and others that advance the iterator. If you want to guarantee the absence of side-effects you will have to use immutable data structures, in any other case your code should only rely on direct effects.

Upvotes: 7

Related Questions