I'm trying to clone a vector of boxed traits.
Naturally simply deriving Clone
on all the structs that implement my trait isn't enough, because the compiler doesn't know at compile time that all the structs implementing the trait have Clone
.
Okay, so I then tried to use Clone
as a supertrait, but that just lead to the error in the title. I'm at a loss for solutions.
Here's the Minimal Working Implementation (or not working, since I can't 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);
}
With this error:
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`
And here's a link to the playground for easy code running.
I've also tried to make the elements
vector in Sequence
a Vec<Box<MusicElement + Clone>>
, but that didn't work either.
I haven't been able to find any useful solutions online, so here's my question: How do I make the code cloneable?