Caution
お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。
Clone / Copy トレイト
CloneトレイトはRustで値のディープコピーを行う仕組みで、Copyトレイトはスタック上のデータを自動コピーする軽量な仕組みです。
構文
// Cloneの導出と使用
#[derive(Clone)]
struct 構造体名 { ... }
let コピー = 元の値.clone();
// Copyの導出(Cloneも必要)
#[derive(Clone, Copy)]
struct 構造体名 { ... }
Clone / Copy 比較一覧
| トレイト | 概要 |
|---|---|
| Clone | 明示的に『.clone()』を呼ぶことで値を複製します。ヒープのデータも含めてコピーします。 |
| Copy | 代入・関数渡しで自動的にコピーされます。スタックのみで表現できる軽量な型に適します。 |
| Copy可能な型 | 整数・浮動小数点・bool・char・参照(&T)・これらのタプル/配列です。 |
| Copy不可の型 | String・Vec・Box など、ヒープを持つ型はCopyを実装できません。 |
サンプルコード
#[derive(Clone, Debug)]
struct Point {
x: f64,
y: f64,
}
#[derive(Clone, Copy, Debug)]
struct Color {
r: u8,
g: u8,
b: u8,
}
fn main() {
// Cloneの使用例
let p1 = Point { x: 1.0, y: 2.0 };
let p2 = p1.clone(); // 明示的にcloneします。
println!("{:?}", p1); // p1はまだ使えます。
println!("{:?}", p2);
// Copyの使用例(自動コピー)
let c1 = Color { r: 255, g: 0, b: 0 };
let c2 = c1; // Copyのため自動コピーされます(moveではありません)。
println!("{:?}", c1); // c1もまだ使えます。
println!("{:?}", c2);
// StringはCopyを実装していないためcloneが必要です。
let s1 = String::from("hello");
let s2 = s1.clone();
println!("{} {}", s1, s2); // 両方使えます。
// プリミティブ型はCopyです。
let x = 42;
let y = x; // 自動コピーです。
println!("x={}, y={}", x, y);
}
概要
『#[derive(Clone)]』マクロを使うと、全フィールドに『clone()』を呼ぶ実装が自動生成されます。フィールドに特殊なクローン処理が必要な場合は手動でCloneトレイトを実装してください。
CopyトレイトはDropトレイトを実装した型には使用できません。ヒープメモリを持つ型はDropが必要なため、Copyを実装することができません。
所有権の移動(move)については所有権 / 移動(move)を参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。