02. Rust 記憶體管理 Copy & Clone(上)
阿新 • • 發佈:2018-12-16
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
屬性.