2017-07-27 42 views
5

我從借用檢查器得到一個Rust編譯錯誤,不知道如何解決它。
下面的代碼很簡單,在C++中類似的代碼沒有問題。如何用這個簡單的代碼滿足Rust借用檢查器?

fn main() { 
    let mut nums = vec![1, 2, 3]; 
    if let Some(x) = nums.last() { 
     nums.push(*x); 
    } 
} 

以下是錯誤:

message: 'cannot borrow `nums` as mutable because it is also borrowed as immutable (4, 9)' 
+1

不知道鏽,它可能不喜歡做NUMS .last()在與nums.push()相同的語句中作爲nums.last()的值在將新條目推入num時可能會更改。 – jwenting

回答

4

可以取消引用後衛子句中的參考:

fn main() { 
    let mut nums = vec![1, 2, 3]; 
    if let Some(&x) = nums.last() { 
     nums.push(x); 
    } 
} 

鏽病具有強大的模式匹配功能,可以解壓幾乎所有的東西,如果你知道它的類型。檢查Rust pattern matching documentation

+0

謝謝,它的工作原理。我認爲nums.last()與nums.push()衝突。 Rust文檔在哪裏詳細解釋了「參考解包」? – LiLei

+0

@李磊,我更新了答案,你應該看看所有的鐵鏽圖案匹配功能(甜蜜如蜜);) – Netwave

7

當您撥打.last()時,您將nums作爲不可變的借用,因爲它會使您所持有的參考x無效。您然後致電.push,其中借用nums爲可變。

的問題是,你現在有一個不可改變的,在同一時間相同的值,這是對鏽病存儲安全保證(的可變借多讀者一個單一的作家保證你將永遠不會有無效的內存任何地方)。

fn main() { 
    let mut nums = vec![1, 2, 3]; 
    if let Some(x) = nums.last() { // Immutable borrow starts here 
     nums.push(*x);    // Mutable borrow starts here 
    }        // Immutable and mutable borrows end here 
} 

該解決方案將是立即放棄其結果的參考,以降低不可改變借的範圍,因爲每@ DanielSanchez的例子:

let mut nums = vec![1, 2, 3]; 
if let Some(&x) = nums.last() { // Immutable borrow starts and ends here 
    nums.push(x);    // Mutable borrow starts here 
}        // Mutable borrow ends here 
+0

謝謝,這個答案比較清楚。我只是不知道爲什麼不變的借款的生活沒有結束。現在我知道原因是nums.last()的返回值是引用。但爲什麼「&x」可以結束Immutable借款? – LiLei

+2

在這種情況下,'&x'實際上取消了'x'。通常情況下,這會移動'x',但是整數實現'Copy'特性,這意味着不是移動'x',而是使用'x'的自動生成副本。我們用dereferencing'x'來銷燬'.last()'返回的引用並結束它引起的借用。 –