2015-01-12 3 views
34

Ich spiele mit Rust, und ich versuche, das erste Befehlszeilenargument mit diesem Code zuzugreifen:Was bedeutet "aus indexiertem Inhalt nicht entfernen"?

use std::env; 

fn main() { 
    let args: Vec<_> = env::args().collect(); 
    let dir = args[1]; 
} 

Und ich bekomme diese Fehlermeldung:

error[E0507]: cannot move out of indexed content 
--> src/main.rs:5:15 
    | 
5 |  let dir = args[1]; 
    |   --- ^^^^^^^ cannot move out of indexed content 
    |   | 
    |   hint: to prevent move, use `ref dir` or `ref mut dir` 

Wenn ich es let ref dir ändern , kompiliert es, aber ich weiß nicht, was los ist. Kann jemand erklären, was "indexierter Inhalt" bedeutet?

Antwort

34

Wenn Sie einen Indexoperator verwenden(), erhalten Sie das tatsächliche Objekt an der Indexposition. Sie erhalten keine Referenz, Zeiger oder Kopie. Da Sie versuchen, dieses Objekt mit einer let Bindung zu binden, versucht Rust sofort zu verschieben (oder zu kopieren, wenn die Copy-Eigenschaft implementiert ist).

In Ihrem Beispiel ist env::args() ein Iterator von String s, der dann in einem Vec<String> gesammelt wird. Dies ist ein besitzter Vektor von eigenen Strings, und eigene Strings können nicht automatisch kopiert werden. Das Verschieben von Vec ist nicht erlaubt, da es in einem ungültigen Zustand bleiben würde - ein Element wird ausgezogen, die anderen nicht.

Sie können eine let ref Bindung verwenden, aber je mehr idiomatische Alternative ist eine Referenz auf das indizierte Objekt zu nehmen (man beachte das & Symbol):

use std::env; 

fn main() { 
    let args: Vec<_> = env::args().collect(); 
    let ref dir = &args[1]; 
    //   ^
} 

Für Ihr spezielles Problem, können Sie auch benutzen Sie einfach Iterator::nth:

use std::env; 

fn main() { 
    let dir = env::args().nth(1).expect("Missing argument"); 
} 
+1

Was passiert, wenn ich besitze das Array, und will das Eigentum an einem einzigen Wert im Array nehmen (und verbrauchen das Eigentum an den arr ay)? – Thayne

+1

Wenn es ein 'Vec' ist, können Sie die Methode' remove' verwenden, andernfalls können Sie 'mem :: replace' den Wert mit einem Dummy-Wert ersetzen. –