2026-08-25
animal_clone_box.rs
trait Animal {
fn speak(&self) -> String;
fn clone_box(&self) -> Box<dyn Animal>;
}
#[derive(Clone)]
struct Dog {
name: String,
}
impl Animal for Dog {
fn speak(&self) -> String {
format!("{} says woof", self.name)
}
fn clone_box(&self) -> Box<dyn Animal> {
// write this: return a boxed clone of self
}
}
Dogのclone_boxを実装してください。DogはCloneをderiveしています。Animal自体にCloneをスーパートレイトとして追加しないこと(Clone::cloneはSelfを返すため、それをするとオブジェクト安全ではなくなりdyn Animalにできなくなります)。
Reference
fn clone_box(&self) -> Box<dyn Animal> {
Box::new(self.clone())
}
self.clone()は具体型Dogを返すのでSelf: Sizedを要求せず、それをBox::newで包んでBox<dyn Animal>に変換しています。clone_box自体は&selfを取りBox<dyn Animal>を返すだけなのでAnimalをオブジェクト安全に保てます。Animal: Cloneとしてしまうとclone(&self) -> Selfがトレイトに入り、そちらはオブジェクト安全ではないためdyn Animalが作れなくなります。これは参考実装であり、唯一の正解ではありません。