2015-01-12 56 views
34

我與Rust玩,我試圖訪問這些代碼的第一個命令行參數:「無法移出索引內容」是什麼意思?

use std::env; 

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

而且我得到這個錯誤:如果我將其更改爲let ref dir

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` 

,它編譯,但我不知道發生了什麼事。有人可以解釋「索引內容」的含義嗎?

回答

34

當您使用索引運算符([])時,您將獲得索引位置處的實際對象。你沒有得到一個參考,指針或複製。既然你試圖用綁定綁定該對象,Rust會立即嘗試移動(或者複製,如果Copy特徵被實現)。

在您的示例中,env::args()String的迭代器,然後將其收集到Vec<String>中。這是擁有的字符串的擁有的矢量,並且擁有的字符串不能自動複製。移出Vec是不允許的,因爲它會使其處於無效狀態 - 一個元素被移出,其他元素不移出。

您可以使用一個let ref結合,但更地道的替代方法是取到索引對象的引用(注意&符號):

use std::env; 

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

爲了您的具體問題,你也可以只是使用Iterator::nth

use std::env; 

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

如果我擁有數組,並且想要獲得數組中單個值的所有權(並且消耗arr的所有權AY)? – Thayne

+1

如果它是'Vec',則可以使用'remove'方法,否則可以用一個虛擬值'mem :: replace'來替換值。 –