2015-06-22 60 views
0

我的代碼:錯誤:使用移動的值 - 我應該使用「&」還是「mut」或其他?

enum MyEnum1 { 
    //.... 
} 

struct Struct1 { 
    field1: MyEnum1, 
    field2: String 
} 

fn fn1(a: Struct1, b: String, c: String) -> String { 
    let let1 = fn2(a.field1); 
    let let2 = fn3(let1, b, c); 
    format!("{} something 123 {}", let1, let2) 
} 


fn fn2(a: MyEnum1) -> String { 
    //.... 
} 

fn fn3(a: MyEnum1, b: Struct1) -> String { 
    //.... 
} 


error: use of moved value: `a.field1` 
error: use of moved value: `let1` 

我怎樣才能解決這些問題?我應該添加&到'fn2 and fn3 ? Or mut`的參數嗎?我無法理解如何解決這類錯誤的想法。

+1

您的代碼會產生與您所描述的不同的錯誤,請提供一個工作示例 –

+1

您的代碼不一致。 'fn3'聲明不同意它是如何被調用的。這段代碼會給你輸入錯誤,而不是所有權。請使你的代碼[一個可編譯的例子](http://stackoverflow.com/help/mcve)。 –

回答

4

這些錯誤來自Rust-ownership中最重要的概念。您應該閱讀the official book,特別是關於ownership的章節 - 這將幫助您瞭解「如何解決這類錯誤」。

總之,特別是在代碼中,問題是,String是非複製的類型,也就是,傳遞給函數或分配給本地變量時String值不復制,它們移動。這意味着無論他們以前在哪裏,他們都無法從那裏進入。

讓我們看一下你的函數:

enum MyEnum1 { 
    //.... 
} 

struct Struct1 { 
    field1: MyEnum1, 
    field2: String 
} 

fn fn1(a: Struct1, b: String, c: String) -> String { 
    let let1 = fn2(a.field1); 
    let let2 = fn3(let1, b, c); 
    format!("{} something 123 {}", let1, let2) 
} 

fn fn2(a: MyEnum1) -> String { 
    //.... 
} 

這裏所有類型都不會自動可拷貝(不執行Copy性狀)。 String不可複製,因爲它是一個堆分配的字符串,複製需要一個新的分配(一個昂貴的操作,最好不要隱式),MyEnum1不可複製,因爲它沒有實現Copy(例如#[deriving(Copy, Clone)];它是不清楚它是否可以複製,因爲你沒有提供它的變體),並且Struct1不可複製,因爲它包含不可複製的類型。

fn1你調用fn2,傳遞它field1並得到String回來。然後,您立即將此String傳遞給fn3。因爲String不可複製,所以let1中存儲的任何內容都是,將轉移到被調用函數中,使得let1不可訪問。這就是「使用移動值」的錯誤所在。 (您提供的代碼不能導致「使用移動的值:a.field1」錯誤,因此它可能來自您省略的部分,但基本思路完全相同)

有幾種方法可以修復這些錯誤,但最自然和最普通的一個確實是使用借來的參考。一般來說,如果你只想讀一個函數的一些不可複製的價值,你應該有它傳遞引用:

fn use_myenum(e: &MyEnum1) 

對於字符串和數組,但是,更好的方式是通過切片:

fn use_str(s: &str) { ... } 

let s: String = ...; 
use_str(&s); // here &String is automatically converted to &str 

你可以在書中找到更多關於切片的文章,here

+0

謝謝,這就是我需要的。有一件事:我如何在'fn use_myenum(e:&MyEnum1)'中刪除'e' - 從指針轉換爲「正常」MyEnum1? –

+0

因爲當我嘗試使用'* e'時,即使這是您正在尋找的答案,我也會收到「錯誤:無法移出借來的內容」 –

+1

,如果您更新問題以包含[MCVE](http://stackoverflow.com/help/mcve) –

相關問題