本文簡要介紹rust語言中 Trait std::marker::Copy 的用法。
用法
pub trait Copy: Clone { }可以簡單地通過複製位來複製其值的類型。
默認情況下,變量綁定有 'move semantics.' 換句話說:
#[derive(Debug)]
struct Foo;
let x = Foo;
let y = x;
// `x` has moved into `y`, and so cannot be used
// println!("{:?}", x); // error: use of moved value但是,如果一個類型實現了 Copy ,則它改為具有 'copy semantics':
// We can derive a `Copy` implementation. `Clone` is also required, as it's
// a supertrait of `Copy`.
#[derive(Debug, Copy, Clone)]
struct Foo;
let x = Foo;
let y = x;
// `y` is a copy of `x`
println!("{:?}", x); // A-OK!需要注意的是,在這兩個示例中,唯一的區別是是否允許您在分配後訪問x。在幕後,複製和移動都可能導致位被複製到內存中,盡管有時這會被優化掉。
如何實現 Copy ?
有兩種方法可以在您的類型上實現Copy。最簡單的是使用 derive :
#[derive(Copy, Clone)]
struct MyStruct;您還可以手動實現Copy 和Clone:
struct MyStruct;
impl Copy for MyStruct { }
impl Clone for MyStruct {
fn clone(&self) -> MyStruct {
*self
}
}兩者之間有一個小小的區別:derive 策略還將在類型參數上放置 Copy 綁定,但這並不總是需要的。
Copy 和 Clone 有什麽區別?
複製是隱式發生的,例如作為分配 y = x 的一部分。 Copy 的行為不可重載;它總是一個簡單的按位複製。
克隆是一個顯式操作,x.clone()。 Clone 的實現可以提供安全複製值所需的任何 type-specific 行為。例如 String 的 Clone 的實現需要複製堆中指向的字符串緩衝區。 String 值的簡單按位複製隻會複製指針,從而導致雙倍釋放。因此, String 是 Clone 但不是 Copy 。
Clone 是 Copy 的超特征,因此 Copy 的所有內容也必須實現 Clone 。如果一個類型是Copy,那麽它的 Clone 實現隻需要返回*self(見上麵的例子)。
我的類型什麽時候可以是 Copy ?
如果一個類型的所有組件都實現了Copy,則該類型可以實現Copy。例如,這個結構可以是 Copy :
#[derive(Copy, Clone)]
struct Point {
x: i32,
y: i32,
}結構可以是 Copy ,而 i32 是 Copy ,因此 Point 有資格成為 Copy 。相比之下,考慮
struct PointList {
points: Vec<Point>,
}結構 PointList 無法實現 Copy ,因為 Vec<T> 不是 Copy 。如果我們嘗試派生 Copy 實現,我們會得到一個錯誤:
the trait `Copy` may not be implemented for this type; field `points` does not implement `Copy`共享參考 (&T) 也是Copy, 所以一個類型可以是Copy,即使它擁有類型的共享引用T那是不是 Copy.考慮以下結構,它可以實現Copy, 因為它隻持有一個共享參考對我們的非Copy類型PointList從上麵:
#[derive(Copy, Clone)]
struct PointListWrapper<'a> {
point_list_ref: &'a PointList,
}什麽時候不能我的類型是Copy?
某些類型無法安全複製。例如,複製 &mut T 將創建一個別名可變引用。複製 String 將重複管理 String 緩衝區的責任,從而導致雙重釋放。
概括後一種情況,任何實現 Drop 的類型都不能是 Copy ,因為它除了自己的 size_of::<T> 字節之外還管理一些資源。
如果您嘗試在包含非 Copy 數據的結構或枚舉上實現 Copy ,您將收到錯誤 E0204 。
什麽時候應該我的類型是Copy?
一般來說,如果您的類型能夠實施Copy, 它應該。但請記住,實施Copy是您的類型的公共 API 的一部分。如果該類型可能變為非Copy將來,謹慎的做法可能是省略Copy現在實施,以避免重大 API 更改。
其他實現者
除了下麵列出的實現者之外,以下類型還實現 Copy :
- 函數項類型(即為每個函數定義的不同類型)
- 函數指針類型(例如,
fn() -> i32) - 元組類型,如果每個組件也實現
Copy(例如,(),(i32, bool)) - 閉包類型,如果它們沒有從環境中捕獲任何值,或者所有這些捕獲的值都實現了
Copy。請注意,共享引用捕獲的變量始終實現Copy(即使引用對象沒有),而可變引用捕獲的變量從不實現Copy。
外來類型的實現
相關用法
- Rust Copy用法及代碼示例
- Rust Condvar.notify_all用法及代碼示例
- Rust Command.args用法及代碼示例
- Rust Condvar.wait用法及代碼示例
- Rust Cow.is_owned用法及代碼示例
- Rust Cow用法及代碼示例
- Rust Condvar.wait_timeout用法及代碼示例
- Rust Condvar.wait_timeout_while用法及代碼示例
- Rust Command.env用法及代碼示例
- Rust Command.env_remove用法及代碼示例
- Rust Command.get_args用法及代碼示例
- Rust Command.stdout用法及代碼示例
- Rust Command.stdin用法及代碼示例
- Rust Components用法及代碼示例
- Rust Component.as_os_str用法及代碼示例
- Rust ControlFlow用法及代碼示例
- Rust Command.current_dir用法及代碼示例
- Rust Command.output用法及代碼示例
- Rust ControlFlow.break_value用法及代碼示例
- Rust Command.status用法及代碼示例
- Rust Cow.into_owned用法及代碼示例
- Rust Condvar.wait_while用法及代碼示例
- Rust Command.envs用法及代碼示例
- Rust Command用法及代碼示例
- Rust Command.get_program用法及代碼示例
注:本文由純淨天空篩選整理自rust-lang.org大神的英文原創作品 Trait std::marker::Copy。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。
