2011-11-28 23 views
7

¿Alguien puede explicar por qué estos iteradores se comportan de manera diferente? En general, espero que una cadena actúe como IndexedSeq[Char]. ¿Está esto documentado en algún lugar?Comportamiento inesperado del iterador en la cadena

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) 
+0

Parece que '.take (2)' en el primer ejemplo hace una copia del iterador. – ziggystar

Respuesta

7

No hay garantías sobre el estado del iterador después de invocar take en él.

El problema con los iteradores es que muchas operaciones útiles solo se pueden implementar causando efectos secundarios. Todas estas operaciones tienen un efecto directo específico pero también pueden tener efectos secundarios que no se pueden especificar (o complicarían la implementación).

En el caso de take hay implementaciones que clonan el estado interno del iterador y otras que hacen avanzar el iterador. Si desea garantizar la ausencia de efectos secundarios, deberá utilizar estructuras de datos inmutables; en cualquier otro caso, su código solo se basará en los efectos directos.

+0

Hmm, me pregunto por qué algo tan crucialmente importante para lo que hace un 'Iterator' no estaría especificado? –

+0

Actualicé la respuesta para resaltar mejor el problema. – Moritz

+2

@LuigiPlinge, hubo algunas mejoras en el enlace troncal en http://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/library/index.html#scala.collection.Iterator: see after " Considere este ejemplo para un uso seguro e inseguro ". – huynhjl

Cuestiones relacionadas