2016-08-05 6 views
5

bewegen Ich bin eine Funktion für eine Struktur zu schreiben, die eine Vec enthält, wo ich durch die Vec zu iterieren versuchen:Iterieren durch eine Vec innerhalb einer Struktur - aus geliehenen Inhalte können nicht

struct Object { 
    pub v: Vec<f32>, 
} 

impl Object { 
    pub fn sum(&self) -> f32 { 
     let mut sum = 0.0; 
     for e in self.v { 
      sum += e 
     } 
     sum 
    } 
} 

Allerdings erhalte ich die folgende Fehler:

error: cannot move out of borrowed content [E0507] 
     for e in self.v { 
       ^~~~ 
help: run `rustc --explain E0507` to see a detailed explanation 

Mein Verständnis ist, dass, da self entliehen ist, und dass die für Schleifeniteration versucht, die Elemente der v hinaus in e zu bewegen?

Aus dem Fehlercode, habe ich gelesen, dass eine mögliche Lösung ist, Besitz zu übernehmen, aber ich bin nicht ganz sicher, wie das geht.

Ich versuche nicht, den Vektor oder seine Elemente zu ändern. Ich möchte nur die Elemente verwenden, um etwas zu berechnen.

+0

verwenden. Sie haben sich die ~ 70 [** andere Fragen mit der gleichen Fehlermeldung **] (http://stackoverflow.com/search?q=%5Brust%5D+cannot+move) angesehen + out + of + geliehen + content + ist% 3Aq)? – Shepmaster

Antwort

13

Die Zeile: sagt im Wesentlichen for e in (*self).v; Sie versuchen, den Vektor durch Verschieben zu durchlaufen, indem Sie sein Merkmal IntoIter aufrufen. Dies würde den Vektor komplett zerstören und alle Zahlen für immer aus ihm entfernen, was nicht nur nicht das ist, was du willst, sondern auch nicht erlaubt in diesem Kontext, weil du es nur lesen darfst.

Sie wollen tatsächlich über Referenz durch iterieren. Es gibt zwei Möglichkeiten, dies zu tun:

for e in &self.v { 
    //... 
} 

Diese im Wesentlichen &((*self).v) sagen, da die . Auto-Dereferenzierungen müssen Sie den Compiler sagen, dass Sie eigentlich nur um den Vektor leihen wollen.

oder

for e in self.v.iter() { 

} 

Das mag komisch aussehen, weil iter eine &self nimmt. Warum? Nun, der Compiler referenziert automatisch, wenn Sie eine Funktion für einen Wert aufrufen, der eine Referenz enthält. Dies ist im Wesentlichen (&((*self).v)).iter(), aber das würde zum Schreiben saugen, so dass der Compiler hilft.

Warum also nicht automatisch in der Schleife for? Nun, for x in self.v ist eine gültige Aussage, und das könnte sein, was Sie schreiben wollten. Es ist normalerweise wichtiger für den Compiler, Ihnen zu sagen, dass das, was Sie wollen, unmöglich ist, als anzunehmen, dass Sie etwas anderes wollen. Bei der obigen automatischen (De-) Referenzierung besteht keine solche Mehrdeutigkeit.

Die erste Lösung wird bevorzugt, letztere ist jedoch erforderlich, wenn Sie einen Iteratoradapter verwenden möchten.

Apropos, Ihre sum existiert bereits in der Nacht. Schreiben Sie einfach self.v.iter().sum(). Ansonsten können Sie self.v.iter().fold(0.0, |(acc, &v)| acc + v)

+0

Super, es funktioniert perfekt. Vielen Dank. Bedeutet das also, dass der Rost-Compiler den Aufruf 'self.struct_member' immer als' (* self) .struct_member' ansieht und aus der Struktur entfernt? Oder ist das speziell für das 'for x in self.v' Konstrukt – illeyezur

+0

@illeyezur Das ist was immer passiert (außer für' Kopieren' Typen, aber das ist, weil 'Kopieren' Typen im Allgemeinen nicht bewegen). – LinearZoetrope

Verwandte Themen