【Rust 標準庫】Copy-Clone 初見
前言
Copy 作爲能夠影響編譯器行爲的 trait 對我們理解 Rust 基礎有着重要作用,而 Clone 是我們作爲搬磚工人能夠自定義複製行爲的 trait。本篇文章將會用最短的篇幅覆蓋 Copy 和 Clone 的主要知識點。
至關重要的 Copy trait
提問,以下代碼爲何 print 1 行不報錯:
extern crate hello_rust;
fn main() {
let num1 = 1i32;
let num2 = num1;
println!("{}", num1); // print 1
println!("{}", num2); // print 2
}
其實這裏就需要理解 Copy trait 在當中起的作用。如果一個類型實現了 Copy trait,那麼它在變量綁定,函數參數傳遞,函數返回值的場景等場景下都是 copy 語義,而不是默認的 move 語義。上面的例子因爲 Rust 已經幫你把 i32 的 Copy trait 實現好了,所以才以 Copy 語義使用。所以,即使是我們自己定義的類型,只要實現了 Copy trait 也會變成 Copy 語義:
extern crate hello_rust;
#[derive(Debug, Copy, Clone)]
struct TA(i32);
fn main() {
let t1 = TA(1);
let t2 = t1;
println!("{:?}", t1); // print 3
println!("{:?}", t2); // print 4
}
Copy trait 對類型有一定要求,如果想讓我們的自定義類型實現 Copy trait,那麼它的所有成員都必須是實現了 Copy trait 的。標準庫除常規 impl 的類型外還特別提及以下類型也是 Copy 的:
1/ 函數 / 函數指針
2/ 元素爲 Copy 的數組和元組
3/ 閉包(不捕獲或者捕獲 Copy)
能夠自定義的 Clone trait
Copy 的行爲我們是無法控制的。如果我們想自定義例如 “類型深複製” 的行爲,可以實現 Clone trait。Copy 是隱式改變編譯器的行爲,而 Clone 需要我們顯式調用:
extern crate hello_rust;
#[derive(Debug, Clone)]
struct CT {
field1: i32,
field2: bool,
}
fn main() {
let ct = CT {
field1: 1,
field2: false,
};
println!("{:?}", ct.clone());
}
如果我們想自定義 Clone trait 的行爲可以手動實現 trait,Rust 不會限制你的具體自定義實現,不過對於同時還要實現 Copy trait 的類型都確保 Clone 和 Copy 代表的語義相同。可以直接在 derive 中二連使用:
impl Clone for CT {
fn clone(&self) -> Self {
*self
}
}
// or
#[derive(Debug, Copy, Clone)]
struct CT {
field1: i32,
field2: bool,
}
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/MEbQoj19Gq10TTxnF2rQEg