02. Rust 記憶體管理 Copy & Clone(上)

劉子殊發表於2018-12-15

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 屬性.

來源:https://juejin.im/post/5c0f2c9d6fb9a049b41c4e4e

相關文章