Namaran

Code daily. Without assist.

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
    }
}

Dogclone_boxを実装してください。DogCloneをderiveしています。Animal自体にCloneをスーパートレイトとして追加しないこと(Clone::cloneSelfを返すため、それをするとオブジェクト安全ではなくなり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が作れなくなります。これは参考実装であり、唯一の正解ではありません。