Ich verstehe den Fehler nicht cannot move out of borrowed content
. Ich habe es oft erhalten und immer gelöst, aber ich habe nie verstanden warum.
Beispielsweise:
for line in self.xslg_file.iter() {
self.buffer.clear();
for current_char in line.into_bytes().iter() {
self.buffer.push(*current_char as char);
}
println!("{}", line);
}
erzeugt den Fehler:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:31:33
|
31 | for current_char in line.into_bytes().iter() {
| ^^^^ cannot move out of borrowed content
In neueren Versionen von Rust ist der Fehler
error[E0507]: cannot move out of `*line` which is behind a shared reference
--> src/main.rs:31:33
|
31 | for current_char in line.into_bytes().iter() {
| ^^^^ move occurs because `*line` has type `std::string::String`, which does not implement the `Copy` trait
Ich habe es durch Klonen gelöst line
:
for current_char in line.clone().into_bytes().iter() {
Ich verstehe den Fehler auch nach dem Lesen anderer Beiträge nicht wie:
- Datei kann nicht von & mut self ausgeliehen werden (Fehlermeldung: Ausgeliehener Inhalt kann nicht verlassen werden)
- Ändern eines Knotens in einem Baum in Rust
Was ist der Ursprung dieser Art von Fehler?
.bytes()
.as_bytes()
as_bytes()
ohne Klonen. Aber ich verstehe immer noch nicht warum?String
bekommt diebytes
Methode vonstr
.Antworten:
Schauen wir uns die Signatur an für
into_bytes
:Dies
self
bezieht sich nicht auf self (&self
). Das bedeutet, dassself
dies verbraucht wird und nach dem Anruf nicht mehr verfügbar ist. An seiner Stelle erhalten Sie eineVec<u8>
. Das Präfixinto_
ist eine gebräuchliche Methode, um solche Methoden zu kennzeichnen.Ich weiß nicht genau, was Ihre
iter()
Methode zurückgibt, aber ich vermute, dass es sich um einen Iterator handelt&String
, das heißt, es gibt Verweise auf a zurückString
, aber Sie erhalten kein Eigentum daran. Das heißt, Sie können keine Methode aufrufen, die den Wert verbraucht .Wie Sie gefunden haben, ist eine Lösung zu verwenden
clone
. Dadurch wird ein doppeltes Objekt erstellt, das Sie besitzen und das Sie aufrufen könneninto_bytes
. Wie andere Kommentatoren erwähnen, können Sie auchas_bytes
die Takes verwenden&self
, sodass ein geliehener Wert verwendet wird. Welches Sie verwenden sollten, hängt von Ihrem Endziel ab, was Sie mit dem Zeiger tun.Im Großen und Ganzen hat dies alles mit dem Begriff des Eigentums zu tun . Bestimmte Operationen hängen vom Besitz des Gegenstands ab, und andere Operationen können mit dem Ausleihen des Objekts (möglicherweise veränderlich) davonkommen. Eine Referenz (
&foo
) gewährt kein Eigentum, sondern nur eine Ausleihe.Die Übertragung des Eigentums ist im Allgemeinen ein nützliches Konzept - wenn ich mit etwas fertig bin, kann es jemand anderes haben. In Rust ist es ein Weg, effizienter zu sein. Ich kann vermeiden, eine Kopie zuzuweisen, Ihnen eine Kopie zu geben und dann meine Kopie wegzuwerfen. Eigentum ist auch der freizügigste Staat; Wenn ich ein Objekt besitze, kann ich damit machen, was ich will.
Hier ist der Code, den ich zum Testen erstellt habe:
quelle