Warum implementiert Vec das Iterator-Merkmal nicht?

8

Was ist der Entwurfsgrund dafür, dass Vecdas IteratorMerkmal nicht implementiert wird? Wenn immer iter()alle Vektoren und Slices aufgerufen werden müssen, entstehen längere Codezeilen.

Beispiel:

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

im Vergleich zu Scala:

val rx = xs.zip(ys)
sge
quelle

Antworten:

14

Ein Iterator hat einen Iterationsstatus. Es muss wissen, was das nächste Element sein wird, das Sie erhalten.

Ein Vektor an sich ist also kein Iterator, und die Unterscheidung ist wichtig. Sie können beispielsweise zwei Iteratoren über denselben Vektor mit jeweils einem bestimmten Iterationsstatus verwenden.

Ein Vektor kann Ihnen jedoch einen Iterator bereitstellen. Deshalb wird er implementiert IntoIterator, sodass Sie Folgendes schreiben können:

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

Viele Funktionen IntoIteratorbenötigen eine Funktion, wenn ein Iterator benötigt wird, und das ist der Fall zip, weshalb

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

kann durch ersetzt werden

let rx = xs.iter().zip(ys);
Denys Séguret
quelle
Gute Antwort! Das einzige, was ich mich gerade frage: Warum xs.zip(ys)arbeitet man dann in Scala? Wird in Scala automatisch ein Iterator (Status) erstellt? Oder enthält sein "Listentyp" immer einen Iteratorstatus? Welche Lösung auch immer Scala verwendet: Warum verwendet Rust sie nicht?
Lukas Kalbertodt
5
Da @ DenysSéguret in Rust, die Unterscheidung zwischen iter(), into_iter()und iter_mut()ist wichtig.
Sebastian Redl
2
@ DenysSéguret du hast recht. Ich würde sagen, es nur für unveränderliche Iteration (mit iter) zu aktivieren und einen expliziten Aufruf iter_mutfür veränderbare Iteration zu erfordern .
Jmb
2
Beachten Sie, dass das gleiche Argument kann gemacht werden , ysin xs.iter().zip (ys): Wie wählen Sie verwenden ys.iter()oder ys.iter_mut()?
Jmb
2
Für verwenden yswir into_iter. Der Grund ist einfach: ysWird verbraucht, so machen andere Iteratorarten keinen Sinn.
Cerberus
4

Was ist der Entwurfsgrund dafür, dass Vecdas IteratorMerkmal nicht implementiert wird?

Welchen der drei Iteratoren sollte es implementieren? Es gibt drei verschiedene Arten von Iteratoren, die Sie von einem erhalten können Vec:

  1. vec.iter()gibt Iterator<Item = &T>,
  2. vec.iter_mut()gibt Iterator<Item = &mut T>und modifiziert den Vektor und
  3. vec.into_iter()gibt Iterator<Item = T>und verbraucht dabei den Vektor.

im Vergleich zu Scala:

In Scala wird es auch nicht Iteratordirekt implementiert , da Iteratorder nächste Elementzeiger benötigt wird, den der Vektor selbst nicht hat. Da Scala jedoch keine Verschiebungssemantik hat, gibt es nur eine Möglichkeit, einen Iterator aus einem Vektor zu erstellen, sodass die Konvertierung implizit durchgeführt werden kann. Rust hat drei Methoden, also muss es dich fragen, welche du willst.

Jan Hudec
quelle
4
into_iter()ist derjenige, der den Vektor verbraucht; drainunterscheidet sich darin, dass nur der Vektor geleert wird.
Trentcl