當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


Rust Copy用法及代碼示例


本文簡要介紹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;

您還可以手動實現CopyClone

struct MyStruct;

impl Copy for MyStruct { }

impl Clone for MyStruct {
    fn clone(&self) -> MyStruct {
        *self
    }
}

兩者之間有一個小小的區別:derive 策略還將在類型參數上放置 Copy 綁定,但這並不總是需要的。

CopyClone 有什麽區別?

複製是隱式發生的,例如作為分配 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

外來類型的實現

1.27.0

__m128d 實現 Copy

1.27.0

__m256 實現 Copy

1.27.0

__m256d 實現 Copy

1.27.0

__m128i 實現 Copy

1.27.0

CpuidResult 實現 Copy

__m256bh 實現 Copy

__m512i 實現 Copy

__m128bh 實現 Copy

__m512d 實現 Copy

1.27.0

__m256i 實現 Copy

__m512bh 實現 Copy

__m512 實現 Copy

1.27.0

__m128 實現 Copy

相關用法


注:本文由純淨天空篩選整理自rust-lang.org大神的英文原創作品 Trait std::marker::Copy。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。