RustのCopy vs Clone: 違いは何ですか?
Grace Collins
Solutions Engineer · Leapcell

良い兄弟: RustのCopyとClone
Rustでは、CopyとCloneトレイトは型のコピー動作を制御します。これらのトレイトを使用すると、型の値がどのようにコピーされるか、およびどのような状況でコピーが許可されるかを定義できます。この記事では、これらの2つのトレイトの目的と使用法を詳細に紹介し、その使用法を示すコード例を示します。
Copyトレイト
Copyトレイトは、型がビットごとにコピーできることを意味します。型がCopyトレイトを実装すると、その値は、割り当て、引数としての受け渡し、または返されるときに自動的に複製されます。
Copyトレイトとは?
Copyトレイトはマーカートレイトです。つまり、メソッドを定義しません。単に型をビット単位のコピーの対象としてマークします。
#[derive(Copy)] struct Point { x: i32, y: i32, }
Copyトレイトを実装する方法?
Copyトレイトを実装するには、#[derive(Copy)]属性を型定義に追加する必要があります。さらに、Copyを実装するすべての型はCloneも実装する必要があるため、型はCloneトレイトも実装する必要があります。
#[derive(Copy, Clone)] struct Point { x: i32, y: i32, }
Cloneも実装せずにCopyを実装しようとすると、コンパイラはエラーをスローします。
#[derive(Copy)] struct Point { x: i32, y: i32, } // error[E0277]: the trait bound `Point: std::clone::Clone` is not satisfied
エラーメッセージは、Point型がCloneトレイトを実装していないため、Copyを実装できないことを示しています。
この要件が存在するのは、すべてのCopy型がCloneも実装する必要があるためです。cloneメソッドを明示的に呼び出すと、Rustはコピーを作成する意図があると見なし、コピー動作が明確に定義されていることを確認したいと考えます。したがって、Copyを実装する場合は、Cloneも実装する必要があります。
どの型がCopyを実装できるか?
すべての型がCopyを実装できるわけではありません。次の基準を満たす型のみが対象となります。
- 型自体が**Plain Old Data (POD)**型であること。つまり、ポインタまたは参照を含まないこと。
- 型のすべてのフィールドも
Copyを実装する必要がある。
たとえば、次の型は参照フィールドが含まれているため、Copyを実装できません。
struct Foo<'a> { x: &'a i32, } // error[E0204]: the trait `Copy` may not be implemented for this type impl Copy for Foo<'_> {}
なぜCopyトレイトが必要なのか?
Copyトレイトを使用すると、型のコピー動作を制御できます。型がCopyを実装すると、その値は割り当て、関数のパラメータ渡し、および戻り時に自動的に複製されます。これにより、値をコピーするために明示的にclone()を呼び出す必要がなくなります。
さらに、Copy型は常にビット単位のコピーを受けるため、パフォーマンスのオーバーヘッドは最小限です。これは、Rustプログラムでパフォーマンスを最適化する場合に特に役立ちます。
Cloneトレイト
Copyとは異なり、Cloneトレイトを使用すると、型の値を明示的にコピーできます。型がCloneを実装すると、そのclone()メソッドを呼び出して新しいインスタンスを作成できます。
Cloneトレイトとは?
Copyとは異なり、Cloneはメソッドclone()を含む通常のトレイトです。このメソッドは、値の新しいコピーを作成する役割を担います。
#[derive(Clone)] struct Point { x: i32, y: i32, }
Cloneトレイトを実装する方法?
Cloneトレイトを実装するには、#[derive(Clone)]属性を追加するか、clone()メソッドを手動で実装します。
#[derive(Clone)] struct Point { x: i32, y: i32, } // `clone()`メソッドの手動実装 impl Clone for Point { fn clone(&self) -> Self { Self { x: self.x, y: self.y } } }
どの型が Cloneを実装できるか?
ほとんどすべての型がCloneを実装できます。値の新しいコピーを作成する方法を定義できる限り、Cloneを実装できます。
なぜCloneトレイトが必要なのか?
Cloneトレイトを使用すると、値を明示的に複製できます。これは、ポインタまたは参照を含むなど、ビット単位でコピーできない型に特に役立ちます。
さらに、Cloneを使用すると、コピープロセスをカスタマイズできます。clone()メソッド内に必要なロジックを追加して、コピー中に特定のアクションを実行できます。
CopyとCloneの違いと関係
CopyとCloneはどちらも型のコピー方法を制御しますが、重要な違いがあります。
Copyはマーカートレイトであり、型がビット単位のコピーをサポートすることを示します。型がCopyを実装すると、その値は、割り当て、関数の引数としての受け渡し、および戻り時に自動的に複製されます。Cloneは、メソッドclone()を含む通常のトレイトです。型がCloneを実装すると、clone()を明示的に呼び出して新しいコピーを作成できます。
さらに、すべてのCopy型はCloneも実装する必要があります。これにより、clone()を明示的に呼び出すと、Rustはあなたが何をしているのかを理解していると見なし、ビット単位のコピーを許可します。
例の分析
以下は、CopyとCloneの使用法を示す例です。
#[derive(Copy, Clone)] struct Point { x: i32, y: i32, } fn main() { let p1 = Point { x: 1, y: 2 }; let p2 = p1; // 自動的にコピー let p3 = p1.clone(); // 明示的にコピー }
この例では、Point型を定義し、CopyとCloneの両方のトレイトを実装します。main関数では、Point値を作成し、別の変数に割り当てます。PointはCopyを実装しているため、割り当て操作は値を自動的に複製します。さらに、clone()を明示的に呼び出して、値の別のコピーを作成します。
Rustプロジェクトのホスティングに最適なLeapcellをご紹介します。
Leapcellは、Webホスティング、非同期タスク、およびRedis向けの次世代サーバーレスプラットフォームです。
多言語サポート
- Node.js、Python、Go、またはRustで開発します。
無制限のプロジェクトを無料でデプロイ
- 使用量に対してのみ料金が発生します - リクエストなし、料金なし。
比類のないコスト効率
- アイドル料金なしの従量課金制。
- 例:$25で、平均応答時間60msで694万リクエストをサポートします。
合理化された開発者エクスペリエンス
- 簡単なセットアップのための直感的なUI。
- 完全に自動化されたCI/CDパイプラインとGitOps統合。
- 実用的な洞察のためのリアルタイムのメトリックとロギング。
簡単なスケーラビリティと高性能
- 高い同時実行性を容易に処理するための自動スケーリング。
- 運用上のオーバーヘッドはゼロ - 構築に集中するだけです。
詳細については、ドキュメントをご覧ください。
Xでフォローしてください:@LeapcellHQ



