問題一覧に戻る
中級トレイト
問題73: トレイトオブジェクト
トレイトオブジェクトはdynキーワードを使った動的ディスパッチを可能にします。同じトレイトを実装する異なる型をコレクションに格納できます。実行時ポリモーフィズムは小さなパフォーマンスコストがありますが柔軟性を提供します。Box'<'dyn Trait'>'でヒープにトレイトオブジェクトを格納するのが一般的です。
trait Draw {
fn draw(&self);
}
struct Circle { radius: f64 }
struct Rectangle { width: f64, height: f64 }
impl Draw for Circle {
fn draw(&self) {
println!("Circle with radius: {}", self.radius);
}
}
impl Draw for Rectangle {
fn draw(&self) {
println!("Rectangle: {} x {}", self.width, self.height);
}
}
// トレイトオブジェクトを受け取る関数
fn draw_shape(shape: & Draw) {
shape.draw();
}
fn main() {
let circle = Circle { radius: 5.0 };
let rect = Rectangle { width: 10.0, height: 20.0 };
// 動的ディスパッチで呼び出し
draw_shape(&circle);
draw_shape(&rect);
// Box化されたトレイトオブジェクト
let shapes: Vec<Box< Draw>> = vec![
Box::new(Circle { radius: 3.0 }),
Box::new(Rectangle { width: 4.0, height: 5.0 }),
];
for shape in &shapes {
shape.draw();
}
}