RUST デイリープロヴィンス: コピー&クローンの類似点と相違点

Rust には Copy と Clone という 2 つの似た特性がありますが、今日はこれら 2 つの特性について話しましょう。

コピー

意味

Copy 特性の内部実装を実装する

pub trait Copy: Clone { }

        この Copytrait は Clone 特性を継承します。つまり、Copy 特性のタイプを実装するには、Clone 特性で定義されたメソッドを実装する必要があります。コピーは std::marker::Copy にあります。Copy トレイト内にはメソッドがなく、その唯一のタスクは型を「マーク」することであることがわかります。単純なメモリ コピーを通じて「マーク」型のコピーを実現できます。型が Copy 特性を実装すると、変数バインディング、関数パラメーターの受け渡し、関数の戻り値の受け渡しなどのシナリオで、デフォルトの移動セマンティクスの代わりにコピー セマンティクスが使用されます。

共通の数値型、bool 型、および条件を実装するための 
        共有借用ポインターは、すべて Copy 属性を持つ型です。Box、Vec、書き込み可能ボローポインター &mut などの型はすべて Copy 属性を持たない型です。配列型の場合、その内部要素型が Copy であれば、この配列も Copy 型になります。タプル型の場合、その各要素がコピー型であれば、このタプルもコピー型になります。struct 型と enum 型は Copy 特性を自動的に実装しません。コンパイラでは、構造体および列挙型内のすべての要素が Copy 型である場合にのみ、この型の Copytrait を実装できます。

クローン

クローンは std::clone::Clone で定義されます
これは次のように実装されます。

pub trait Clone : Sized {
fn clone(&self) -> Self;
fn clone_from(&mut self, source: &Self) {
*self = source.clone()
}
}

        これには、clone_from と clone という 2 つの関連メソッドがあります。clone_from にはデフォルトの実装があり、clone メソッドの実装に依存します。clone メソッドにはデフォルトの実装がないため、手動で実装する必要があります。

実装
        Box タイプの場合、clone は「ディープ コピー」を実行します。Rc タイプの場合、clone は参照カウント値に 1 を加算します。Rust の clone メソッドは通常、コピー操作を実行するために使用されますが、カスタム clone 関数で別のことを実行した場合、コンパイラにはそれを禁止する方法がありません。clone関数には必要に応じて任意のロジックを記述することができます。ただし、注意すべきルールがあります。コピーを実装する型の場合、その clone メソッドはコピー セマンティクスと互換性がある必要があり、これはバイト単位のコピーと同等です。

派生は自動的に実装されます


       なぜなら、コピー クローンのような特性の実装は基本的に反復的で退屈な作業だからです。したがって、derive を使用すると、impl Copy や impl Clone などのコードを自動的に生成できます。自動生成された clone メソッドは、各メンバーの clone メソッドを順番に呼び出します。使用方法は次のとおりです。

#[derive(Copy, Clone, Debug)]
struct Csdns;

要約する


Copy と Clone の違いと関連性は次のとおりです。

  • Copy 内にはメソッドはありませんが、Clone 内には 2 つのメソッドがあります。Copy トレイトではメソッドが定義されていないため、このプロセス中に追加のコードは実行されません。とはいえ、値のコピーは非常に高速であると考えられます。
  • Copy 特性はコンパイラ用であり、この型のデフォルトが移動セマンティクスではなくコピー セマンティクスであることをコンパイラに伝えます。Clone 特性はプログラマ向けであり、clone メソッドは手動で呼び出す必要があります。
  • Copy トレイトは、考えただけで実装できるものではなく、型に対する要件があり、型によっては Copy を実装できないものもあります。Clone 特性には前提条件がなく、任意のタイプを実装できます。
  • Copy 特性は、この型が変数バインディング、関数パラメーターの受け渡し、関数戻りなどのシナリオで「単純なメモリ コピー」操作を実行する必要があることを規定しています。これはコンパイラによって保証されており、プログラマによって制御することはできません。Clone トレイトの clone メソッドが何を行うかは、プログラマが作成したロジックによって異なります。一般に、クローン メソッドは「ディープ コピー」操作を実行する必要があります。
  • ·他のカスタム操作を実行するために Clone 特性が本当に必要ない場合 (これはほとんどの場合に当てはまります)、コンパイラーが提供するツールを使用して、 #[derive(Clone)] を型に追加して、コンパイラーがそれらの繰り返しコードを自動的に生成できるようにします。コンパイラによって自動的に生成される clone メソッドは、各メンバーの clone メソッドを順番に呼び出すという非常に機械的なものです。

おすすめ

転載: blog.csdn.net/xq723310/article/details/130217182