Ich versuche herauszufinden, warum das nicht funktioniert ( Spielplatz ):
%Vor%Fehler:
%Vor%Aber das funktioniert:
%Vor% Bitte erläutern Sie, wie Vektoren in Rust arbeiten und den Unterschied, wenn ich iter()
.
Kurz gesagt : Sie haben wahrscheinlich die Rangfolge der Operatoren falsch verstanden:
%Vor%Ist gleich:
%Vor% Und da zip()
etwas erwartet, das IntoIterator
implementiert, schlägt der Aufruf fehl, da ein Verweis auf diesen Iteratortyp dieses Merkmal nicht implementiert.
Versuchen wir, die Fehlermeldung zu verstehen! Natürlich sehen wir uns zuerst den ersten Fehler an:
%Vor% Wow, das ist ein ziemlicher Bissen. Aber wir können sehen, dass einige merkmalsgebundene Anforderungen der Funktion zip()
wird verletzt. Schauen wir uns die Signatur der Funktion an:
Wichtig ist das Argument other
(Typ U
). U
muss IntoIterator
sein. Dieses Merkmal ist für einige Arten implementiert ... lasst uns prüfen, welchen Typ wir in zip()
übergeben wollen:
Um das vollständig zu analysieren, müssen wir etwas verstehen, aber ich werde versuchen, es zu durchbrechen. Lassen Sie uns zunächst die Rangfolge der Operatoren durch Einfügen weiterer Klammern unterscheiden. Das obige Code-Snippet entspricht:
%Vor% Ein Ausdruck foo[bar]
desugares to *::std::ops::Index::index(&foo, bar)
. Dies ist der komplexeste Teil hier, aber wenn Sie in der Dokumentation nachsehen, hat der Ausdruck b[1..b.len()]
den Typ [i32]
.
Bei diesem Typ rufen Sie iter()
auf gibt einen Typ Iter<_, _>
zurück, der der Iteratortyp für Slices ist.
Jetzt die &
: Sie leihen diese Iter<_, _>
Sache, was in &Iter<_, _>
resultiert.
Und hey, das stimmt mit der Fehlermeldung überein! Schau dir die letzte Notiz an:
%Vor% Also ... was erfüllt die Eigenschaft IntoIterator
? Zum einen implementiert jeder Typ, der Iterator
implementiert (z. B. Iter<_, _>
) auch IntoIterator
. Sie können also &
im Ausdruck entfernen und es funktioniert!
Aber wir können es noch besser machen! IntoIterator
ist auch für &[T]
implementiert, also kannst du auch einfach .iter()
entfernen und es funktioniert!
Hinweis : Ich habe auch die oberen Grenzen der Bereiche entfernt, um sie halboffen zu machen, wie Paolo Falabella vorgeschlagen hat .
Ihre erste Version hat ein Problem mit der Vorrangstellung des Operators: &a[1..a.len()].iter()
wendet zuerst iter()
an und nimmt dann eine Referenz darauf, die mit einem Verweis auf std::slice::Iter
endet.
Wie Sie in den Dokumenten für Iter
sehen können, gibt es ein impl Iterator
für Iter
, aber nicht für &Iter
.
Dies ist es, was der erste Fehler versucht zu sagen: (Schauen Sie sich den Teil an, der sagt: &std::slice::Iter<'_, {integer}>
ist kein Iterator).
Vereinfacht ein bisschen, können Sie haben:
%Vor% Iterator::zip
erwartet etwas, das IntoIterator
implementiert.
Anstatt ein Iterator
zu übergeben, geben Sie eine Referenz an Iterator
. Iterator
s mutieren und eine Referenz ist nicht ausreichend.
Sie können dies beheben, indem Sie Klammern verwenden, um zu verdeutlichen, was Sie versuchen, eine Referenz von
zu erhalten %Vor%Tags und Links rust