Was muss ich tun, um die Lösung "Einsatz von bewegt-Wert" - Fehler?
Ich versuche zu berechnen, der 10,001 st prime in Rust (Projekt Euler 7), und als Teil dieser, meine Methode, um zu überprüfen, ob oder nicht eine ganze Zahl ist prim verweist auf einen Vektor:
fn main() {
let mut count: u32 = 1;
let mut num: u64 = 1;
let mut primes: Vec<u64> = Vec::new();
primes.push(2);
while count < 10001 {
num += 2;
if vectorIsPrime(num, primes) {
count += 1;
primes.push(num);
}
}
}
fn vectorIsPrime(num: u64, p: Vec<u64>) -> bool {
for i in p {
if num > i && num % i != 0 {
return false;
}
}
true
}
Wenn ich versuche, eine Referenz der Vektor, bekomme ich die folgende Fehlermeldung:
error[E0382]: use of moved value: `primes`
--> src/main.rs:9:31
|
9 | if vectorIsPrime(num, primes) {
| ^^^^^^ value moved here, in previous iteration of loop
|
= note: move occurs because `primes` has type `std::vec::Vec<u64>`, which does not implement the `Copy` trait
Was muss ich tun, um primes
um der Lage sein, um den Zugang innerhalb der vectorIsPrime
Funktion?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Mit der aktuellen definition der Funktion
vectorIsPrime()
, die Funktion gibt an, dass es erfordert Besitz der parameter, da Sie es passieren von Wert.Wenn eine Funktion einen parameter benötigt, die von Wert, der compiler überprüfen, ob der Wert kopiert werden kann, indem überprüft wird, ob es implementiert das Merkmal
Copy
.Das ist die Bedeutung von der Fehlermeldung, die Sie haben.
Jedoch die meisten Funktionen nicht erforderlich Eigentum der Parameter: Sie können die Arbeit an "geliehene Referenzen", was bedeutet, dass Sie nicht tatsächlich den Wert (und nicht zum Beispiel steckte es in einen container oder zu zerstören).
Die Funktion
vector_is_prime()
gibt jetzt an, dass es nur noch eine Scheibe, d.h. eine geliehene Zeiger auf ein array (einschließlich der Größe), Sie kann erhalten von einem Vektor mit dem ausleihen Betreiber&
.Weitere Informationen über das Eigentum, fordere ich Sie auf, Lesen Sie den Teil des Buch beschäftigt sich mit Eigentum.
i
imfor &i in p{
erfordern eine&
vor? Der code löst beim kompilieren Fehler ohne es, und ich bin neugierig, warum.i
ist ein Verweis, und so also in der Schleife, i wird der Wert, sondern als Referenz. wenn Sie lassen Sie es aus, Sie brauchen würde *ich ' s, wenn dabei die Vergleiche.Rost ist, wie ich sagen würde, ein "Wert-orientierte" Sprache. Dies bedeutet, dass, wenn Sie definieren Primzahlen wie diese
ist es nicht eine Referenz auf einen vector. Es ist praktisch eine variable, in der ein Wert Typ
Vec<u64>
wie jedeu64
variable speichert eineu64
Wert. Dies bedeutet, dass, wenn Sie übergeben es an eine Funktion, die wie folgt definiertdie Funktion seinen eigenen
u64
Wert und seine eigeneVec<u64>
Wert.Den Unterschied zwischen
u64
undVec<u64>
ist jedoch, dass einu64
Wert kann leicht an eine andere Stelle kopiert werden, während eineVec<u64>
Wert kann nur bewegen an einen anderen Ort leicht. Wenn Sie möchten, geben Sie dievec_is_prime
Funktion seine eigenenVec<u64>
Wert, während man für sich selbst in den main, Sie haben, es zu duplizieren, irgendwie. Das ist es, wasclone()
ist für. Der Grund, Sie haben explizit hier ist, weil diese operation ist nicht Billig. Das ist eine nette Sache über Rost: Es ist nicht schwer zu erkennen ist kostspielig. Also, Sie könnte rufen Sie die Funktion wie folgtaber das ist nicht wirklich, was du willst, eigentlich. Die Funktion benötigt keine eigene ein
Vec<64>
Wert. Es muss nur leihen es für eine kurze Weile. Borgen ist viel effizienter und gilt in diesem Fall:Aufrufen, es benötigt nun, dass das "borrowing Betreiber":
Viel besser. Aber wir können noch besser werden. Wenn eine Funktion will, leihen Sie sich ein
Vec<T>
nur für den Zweck, es zu Lesen, es ist besser einen&[T]
statt:Geht es nur mehr allgemein. Jetzt können Sie verleihen einen gewissen Teil von Vec, um die Funktion oder etwas völlig anderes (nicht unbedingt ein
Vec
, solange diese etwas speichert seine Werte hintereinander im Speicher, wie einen statischen lookup-Tabelle). Was auch schön ist, dass aufgrund coersion Regeln, die Sie nicht brauchen, etwas zu ändern an der call-site. Sie können immer noch rufen diese Funktion mit&primes
als argument.Für
String
und&str
die situation ist die gleiche.String
ist für die Speicherung von string-Werten in dem Sinne, dass eine variable dieses Typs besitzt Wert.&str
ist für die Anleihe die Ihnen.i
muss so geschrieben werden, als&i
.i
wo Sie es verwenden.Copy
oderClone
. Wenn Sie&i
in der for-Schleifei
wird eine Kopie der ein vector-element.Bewegen Sie Wert
primes
um die FunktionvectorIsPrime
(BTW Rost verwendensnake_case
per Konvention). Sie haben andere Möglichkeiten, aber das beste ist, um zu leihen, Vektor, statt Sie zu verschieben:Und dann beiläufig erwähnt er: