12

ボックス化された特性のベクターを複製しようとしています。当然のことながらClone、私の特性を実装するすべての構造体を単に派生させるだけでは十分ではありません。なぜなら、コンパイラは、特性を実装するすべての構造体がClone.

さて、それで私はCloneスーパートレイトとして使用しようとしましたが、それはタイトルのエラーにつながりました. 私は解決策に途方に暮れています。

これが最小限の実用的な実装です(または、複製できないため、機能していません)

#![allow(dead_code, unused_macros)]
use std::fmt::Debug;

trait MusicElement: Debug + Clone {
    fn duration(&self) -> f32;
}

#[derive(Debug, Clone)]
struct Note<'a> {
    name: &'a str,
    duration: f32,
}

impl<'a> MusicElement for Note<'a> {
    fn duration(&self) -> f32 {
        self.duration
    }
}

#[derive(Debug, Clone)]
struct Pause {
    duration: f32,
}

impl MusicElement for Pause {
    fn duration(&self) -> f32 {
        self.duration
    }
}

#[derive(Debug, Clone)]
struct Sequence {
    elements: Vec<Box<MusicElement>>,
}

impl MusicElement for Sequence {
    fn duration(&self) -> f32 {
        self.elements.iter().map(|e| e.duration()).sum()
    }
}

fn main() {
    let a4 = |dur| Box::new(Note { name: "a4", duration: dur });
    let seq = Sequence { elements: vec![a4(0.25), a4(0.25), a4(0.5)] };
    println!("{:?}", seq);
    let seq2 = seq.clone();
    println!("{:?}", seq2);
}

このエラーで:

error[E0038]: the trait `MusicElement` cannot be made into an object
  --> src/main.rs:33:5
   |
33 |     elements: Vec<Box<MusicElement>>,
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MusicElement` cannot be made into an object
   |
   = note: the trait cannot require that `Self : Sized`

簡単にコードを実行できるプレイグラウンドへのリンクを次に示します。

elementsでベクトルを作成しようとしましSequenceVec<Box<MusicElement + Clone>>が、それもうまくいきませんでした。

オンラインで有用な解決策を見つけることができなかったので、ここに私の質問があります: コードを複製可能にするにはどうすればよいですか?

4

2 に答える 2