Ich bin neu in Rust und habe noch nicht alles verstanden. Ich habe viel Rust gelesen und spiele auch mit Mathe-Problemen. Ich schrieb eine Funktion mit dieser Signatur:.next() after for ... .zip(): Verhindere, dass der Iterator verschoben wird
pub fn prime_factors(n: u64) -> Vec<u64> {
So
, da n
von 30, sollte es einen Vektor mit den Werten 2 zurückkehren, 3 und 5. ich einen Test gebaut, der lautet:
#[test]
fn prime_factors_test() {
assert_list_eq([2,3,5].iter(), prime_factors(30).iter());
}
Ein Highlight ist, dass ich ein statisches Array mit einem Vektor vergleiche (zu Lernzwecken ist dies derzeit wünschenswert, weil ich gerne Generika praktizieren möchte).
Meine Testfunktion ist die, mit der ich eigentlich Probleme habe. Zum Testen muss die Funktion beide Auflistungen durchlaufen und auf Gleichheit mit jedem Index prüfen. Ich habe .zip()
verwendet, um dies zu tun, aber wenn die Sammlungen ungleich sind, wird der Iterator nur durch den Index der kürzeren ausströmen. Nach zip
möchte ich überprüfen, ob einer der Iteratoren zusätzliche Elemente enthält.
Die folgende lässt sich nicht kompilieren:
fn assert_list_eq<I, T>(mut expected: I, mut actual: I)
where I: Iterator<Item=T> + Clone,
T: PartialEq + Debug {
for (e, a) in expected.zip(actual) {
assert_eq!(e, a);
}
// fail if there are any "leftovers"
assert_eq!(None, expected.next());
assert_eq!(None, actual.next());
}
Ich denke, die Schleife (oder vielleicht das Setup für die Schleife) bewegt/die Iteratoren verbraucht, und sie können nicht nach der Schleife verwendet werden. Aber ich wollen auf den Status dieser Iteratoren Post-Schleife überprüfen. Ich denke, ich weiß, was ist falsch, ich weiß nur nicht, wie man es rechts. Ich habe fast sicher ein konzeptionelles Problem.
Als Workaround habe ich das getan, aber ich fühle mich wie ich ein Anti-Muster umarmen mit dem .clone()
nur um die Dinge funktionieren zu lassen.
fn assert_list_eq<I, T>(expected: I, actual: I)
where I: Iterator<Item=T> + Clone,
T: PartialEq + Debug {
assert!(expected.clone().count() == actual.clone().count()); // desperation
for (e, a) in expected.zip(actual) {
assert_eq!(e, a);
}
}
BTW (Anerkennung XY Problem): Ich sei glücklich, eine eingebaute Behauptung zu lernen zwei geordnete Sammlungen zu vergleichen, aber das ist nicht wirklich, was ich bin verwirrt.
Wenn Sie Iteratoren anstelle von Slices vergleichen möchten, gibt es auch ['Iterator :: eq'] (http://doc.rust-lang.org/std/iter/trait.Iterator.html#method. eq) in der Standardbibliothek und ['assert_equal'] (http://bluss.github.io/rust-itertools/doc/itertools/fn.assert_equal.html) in Itertools. – Shepmaster