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