1. 程式人生 > >02. Rust 記憶體管理 Copy & Clone(上)

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

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