¿Por qué Vec no implementa el rasgo Iterator?


8

¿Cuál es la razón del diseño para Vecno implementar el Iteratorrasgo? Tener que recurrir siempre iter()a todos los vectores y cortes hace que las líneas de código sean más largas.

Ejemplo:

let rx = xs.iter().zip(ys.iter());

en comparación con Scala:

val rx = xs.zip(ys)

Respuestas:


14

Un iterador tiene un estado de iteración. Debe saber cuál será el próximo elemento para darle.

Entonces, un vector en sí mismo no es un iterador, y la distinción es importante. Puede tener dos iteradores sobre el mismo vector, por ejemplo, cada uno con su estado de iteración específico.

Pero un vector puede proporcionarle un iterador, por eso se implementa IntoIterator, lo que le permite escribir esto:

let v = vec![1, 4];
for a in v {
    dbg!(a);
}

Muchas funciones toman un IntoIteratorcuando se necesita un iterador, y ese es el caso zip, razón por la cual

let rx = xs.iter().zip(ys.iter());

puede ser reemplazado con

let rx = xs.iter().zip(ys);

¡Gran respuesta! Lo único que me pregunto ahora: ¿por qué xs.zip(ys)funciona en Scala entonces? ¿Se crea automáticamente un iterador (estado) en Scala? ¿O su "tipo de lista" siempre contiene un estado iterador? Cualquier solución que use Scala: ¿por qué Rust no la usa?
Lukas Kalbertodt

55
@ DenysSéguret Porque en Rust, la distinción entre iter(), into_iter()y iter_mut()es importante.
Sebastian Redl

2
@ DenysSéguret tienes razón. Yo diría que solo lo habilite para la iteración inmutable (usando iter) y requiera una llamada explícita a la iter_mutiteración mutable.
Jmb

2
Tenga en cuenta que se puede hacer el mismo argumento ysen xs.iter().zip (ys): ¿cómo elige usar ys.iter()o ys.iter_mut()?
Jmb

2
Para ys, usamos into_iter. La razón es simple: ysse consume, por lo que otros tipos de iteradores no tienen sentido.
Cerberus el

4

¿Cuál es la razón del diseño para Vecno implementar el Iteratorrasgo?

¿Cuál de los tres iteradores debería implementar? Hay tres tipos diferentes de iterador que puede obtener de Vec:

  1. vec.iter()da Iterator<Item = &T>,
  2. vec.iter_mut()da Iterator<Item = &mut T>y modifica el vector y
  3. vec.into_iter()da Iterator<Item = T>y consume el vector en el proceso.

en comparación con Scala:

En Scala tampoco se implementa Iteratordirectamente, porque Iteratornecesita el siguiente puntero de elemento que el vector en sí no tiene. Sin embargo, dado que Scala no tiene semántica de movimiento, solo tiene una forma de crear un iterador a partir de un vector, por lo que puede hacer la conversión implícitamente. Rust tiene tres métodos, por lo que debe preguntarte cuál quieres.


44
into_iter()es el que consume el vector; draines diferente porque solo vacía el vector.
trentcl
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.