Caution
お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。
#[derive(Debug, Clone, PartialEq)]
Rustの『#[derive]』属性を使うと、『Debug』『Clone』『PartialEq』などのトレイトを自動実装できます。手動実装が不要になり、コードが大幅に短くなります。
構文
// derive属性でトレイトを自動実装します。
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
struct Point {
x: i32,
y: i32,
}
// Debug: {:?} または {:#?} で出力できます。
let p = Point { x: 1, y: 2 };
println!("{:?}", p); // Point { x: 1, y: 2 }
println!("{:#?}", p); // 整形されて出力されます。
// Clone: .clone() でディープコピーができます。
let p2 = p.clone();
// PartialEq: == で比較できます。
assert_eq!(p, p2);
// Default: デフォルト値でインスタンスを生成します(数値は0、boolはfalse、StringはString::new())。
let zero = Point::default(); // Point { x: 0, y: 0 }
主なderiveトレイト一覧
| トレイト | 概要 |
|---|---|
| Debug | {:?} / {:#?} でデバッグ出力できるようになります。開発中は常に付けることを推奨します。 |
| Clone | .clone() でディープコピーができます。Stringなどのヒープデータもコピーされます。 |
| Copy | 代入時に暗黙的にコピーされます(Clone も必須)。全フィールドがCopyの場合のみ使えます。 |
| PartialEq | == / != で比較できます。全フィールドを比較します。 |
| Eq | PartialEqに加え同値関係の完全性を示します(f64などNaNがある型には使えません)。 |
| PartialOrd | < / > / <= / >= で大小比較できます(PartialEqも必要)。 |
| Ord | 全順序(sort等)に使えます(PartialOrd / Eq / PartialEqも必要)。 |
| Hash | HashMapのキーとして使えます(Eq も必要)。 |
| Default | ::default() でデフォルト値のインスタンスを生成できます。 |
サンプルコード
use std::collections::HashMap;
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
struct Color {
r: u8,
g: u8,
b: u8,
}
#[derive(Debug, Clone, PartialEq)]
struct Player {
name: String,
score: i32,
color: Color,
}
fn main() {
// Debug: デバッグ出力します。
let red = Color { r: 255, g: 0, b: 0 };
println!("{:?}", red); // Color { r: 255, g: 0, b: 0 }
println!("{:#?}", red); // 整形されて出力されます。
// Clone: ディープコピーします。
let red2 = red.clone();
println!("cloned: {:?}", red2);
// PartialEq: == で比較します。
println!("red == red2: {}", red == red2); // true
let blue = Color { r: 0, g: 0, b: 255 };
println!("red == blue: {}", red == blue); // false
// Hash: HashMapのキーとして使います。
let mut palette: HashMap<Color, &str> = HashMap::new();
palette.insert(red.clone(), "red");
palette.insert(blue.clone(), "blue");
println!("パレット: {:?}", palette.get(&red)); // Some("red")
// Default: デフォルト値を生成します(全て0)。
let black = Color::default();
println!("default color: {:?}", black); // Color { r: 0, g: 0, b: 0 }
// ネストした構造体のClone / PartialEqです。
let p1 = Player {
name: String::from("Alice"),
score: 100,
color: red.clone(),
};
let p2 = p1.clone();
println!("p1 == p2: {}", p1 == p2); // true
// PartialOrd と Ord を使った構造体です(全フィールドがOrdの場合)。
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Version {
major: u32,
minor: u32,
patch: u32,
}
let mut versions = vec![
Version { major: 1, minor: 2, patch: 0 },
Version { major: 2, minor: 0, patch: 0 },
Version { major: 1, minor: 1, patch: 5 },
];
versions.sort();
println!("バージョンソート: {:?}", versions);
}
概要
『#[derive]』は全フィールドが同じトレイトを実装していないと使えません。例えば、全フィールドが『Copy』の場合のみ構造体に『Copy』を導出できます。
『PartialEq』は構造体の全フィールドを順番に比較します。特定のフィールドだけを比較したい場合や、浮動小数点のカスタム比較が必要な場合は手動で実装します。
構造体の定義は『struct / フィールド定義』を、メソッドの定義は『impl / メソッド定義』を参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。