02. Rust 記憶體管理 Copy & Clone(上)
Rust 語法上一個變數的值是轉移給另一個變數, 但是有些情況下可能會想變數值轉移之後, 自身還能繼續使用. 可以使用clone
函式
let a = String::from("test"); let b = a.clone(); println!("{}", a); 複製程式碼
clone
這個函式是在標準庫的std::clone::Clone
trait 裡, 既然是個 trait, 也就意味著可以自己實現一套操作, 通常情況下用預設的定義就好了.
Copy
我們現在瞭解到每次繫結變數, 都會發生所有權轉移, 但是你會發現寫有些東西的時候好像行為跟目前的認知有點不一樣.
let a: i32 = 10; let b = a; println!("a = {}", a); // a = 10 複製程式碼
a
沒有使用clone
還能使用, 原因是 Rust 有部分型別預設實現了std::marker::Copy
trait, 也就是整型浮點型這類基本型別. 像structs
這類沒有預設實現的型別, 想要這樣就得實現一下Copy
.
fn main() { let p1 = Point { x: 1.0, y: 1.0 }; let p2 = p1; println!("p1 = {:?}", p1); } #[derive(Debug)] struct Point { x: f64, y: f64, } impl Copy for Point {} 複製程式碼
但是其實這樣還是沒法用的, 編譯後就報錯了, 因為struct Point
沒有實現Clone
trait.
pub fn main_8_6() { let p1 = Point { x: 1.0, y: 1.0 }; let p2: Point = p1; println!("p1 = {:?}", p1); } #[derive(Debug)] struct Point { x: f64, y: f64, } impl Clone for Point { fn clone(&self) -> Self { Self { x: self.x, y: self.y } } } impl Copy for Point {} 複製程式碼
現在終於好使了. 但是我們發覺做這些操作非常煩, 我們注意到#[derive(Debug)]
這個東西, 剛好 Rust 提供了Clone
,Copy
的屬性.
pub fn main_8_6() { let p1 = Point { x: 1.0, y: 1.0 }; let p2: Point = p1; println!("p1 = {:?}", p1); } #[derive(Debug, Clone, Copy)] struct Point { x: f64, y: f64, } 複製程式碼
Rust 預設繫結變數是進行move
行為, 想要保留move
前的變數, 可以使用clone
函式, 想要實現基本型別一樣的copy
行為, 我們可以新增Clone
,Copy
屬性.