Rust 未繫結可變引用 和繫結可變引用的區別
阿新 • • 發佈:2018-12-18
Rust 繫結可變引用 和可變繫結的區別
在Rust Documents Api 中 我們經常會看到如下的寫法
//繫結可變引用
let f = &mut String::from("what something");
//可變繫結
let mut f = String::from("what something");
這兩種語法的區別是很大的。比如在如下程式碼中:
fn main(){ let mut j; { let f = &mut String::from("what something"); j = f; // string "what something" died in the scope } j.push('.'); print!("{}\n",j); }
fn main(){
let mut j;
{
let f = String::from("what something");
j = f;
}
j.push('.');
print!("{}\n",j);
}
第一種寫法會編譯報錯。而第二種寫法則可以正常執行。其原因是Rust的所有權規則: 在Rust中 所有值(分配在堆上或者分配在棧上的記憶體)有且只有一個稱之為所有者的變數(繫結)。 值有且只有一個所有者。當所有者離開作用域時,這個值(記憶體)將被丟棄。
在第一種寫法中,"String::from("what something")
並沒有一個所有者變數。這叫做一個temporary value
j = f
在遇到第一個}
時無效。此時j指向的值被丟棄。編譯器會報錯。
在第二種寫法中,f 是String::from("what something")
的擁有者,當呼叫j = f
時 String::from("what something")
被移動到了 j
變數中,因此在第一個}
之後記憶體並被沒有被回收。所以第二種寫法可以編譯通過。
結論
當在函式呼叫時,我們需要一些臨時變數來當作引數值,並確定之後不會使用,則可以使用&mut String::("what something")
這在某些時候是很有用的。
然而,如果我們不想rustc釋放掉某塊記憶體,我們必須指定一個記憶體的所有者,並通過移動語義確保其所有者有效。