Rust Can';t克隆向量<;盒子<;特质>&燃气轮机;因为特质不能被制造成一个物体

Rust Can';t克隆向量<;盒子<;特质>&燃气轮机;因为特质不能被制造成一个物体,rust,clone,trait-objects,Rust,Clone,Trait Objects,我想克隆一个盒状特征的载体。 当然,仅仅在实现my trait的所有结构上派生Clone是不够的,因为编译器在编译时不知道实现该trait的所有结构都有Clone 好的,然后我尝试使用Clone作为超级特征,但这只会导致标题中的错误。我找不到解决办法 这是最小的工作实现(或者不工作,因为我不能克隆) #![允许(死\u代码、未使用的\u宏)] 使用std::fmt::Debug; 特征音乐加速:调试+克隆{ fn持续时间(&self)->f32; } #[派生(调试、克隆)] 结构注释{ fn持

我想克隆一个盒状特征的载体。 当然,仅仅在实现my trait的所有结构上派生
Clone
是不够的,因为编译器在编译时不知道实现该trait的所有结构都有
Clone

好的,然后我尝试使用
Clone
作为超级特征,但这只会导致标题中的错误。我找不到解决办法

这是最小的工作实现(或者不工作,因为我不能克隆)

#![允许(死\u代码、未使用的\u宏)]
使用std::fmt::Debug;
特征音乐加速:调试+克隆{
fn持续时间(&self)->f32;
}
#[派生(调试、克隆)]
结构注释{
fn持续时间(自身)->f32{
自我持续时间
}
}
#[派生(调试、克隆)]
结构暂停{
持续时间:f32,
}
为暂停而实施音乐加速{
fn持续时间(自身)->f32{
自我持续时间
}
}
#[派生(调试、克隆)]
结构序列{
元素:Vec,
}
序列的impl音乐加速{
fn持续时间(自身)->f32{
self.elements.iter().map(| e | e.duration()).sum()
}
}
fn main(){
设a4=| dur | Box::new(注{名称:“a4”,持续时间:dur});
设seq=序列{元素:vec![a4(0.25),a4(0.25),a4(0.5)];
println!(“{:?}”,seq);
设seq2=seq.clone();
println!(“{:?}”,seq2);
}
出现此错误时:

error[E0038]:无法将特征'MusicElement'制作成对象
-->src/main.rs:33:5
|
33 |元素:Vec,
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
=注意:该特征不能要求“Self:Sized”`
这里有一个简单的代码运行方法

我还尝试将
序列中的
元素
向量
a
Vec
,但也没有成功


我还没有在网上找到任何有用的解决方案,所以我的问题是:如何使代码可克隆?

解决方案在于结合到目前为止评论中的建议-中的答案告诉您必须为所有兼容(
'static+MusicElement+Clone
)类型创建一个全面的特性实现。实现所需的唯一后续步骤是将
注释.name
字段的类型从
&'a str
更改为
字符串
,:

#![允许(死\u代码、未使用的\u宏)]
使用std::fmt::Debug;
特征MusicElement:MusicElement克隆+调试{
fn持续时间(&self)->f32;
}
特征音乐克隆{
fn克隆盒(&self)->盒;
}
impl我的板条箱提供了一个可重用的实现。有了它,您可以使您的原始代码只需最少的更改即可工作


之前: 之后:
可能重复:@电咖啡:这对你有帮助吗?我得到一个错误,说
note为什么不使用
String
作为名称?实现
Clone
对你的业务逻辑真的很有必要吗?导致此错误的原因是Rust编译器需要在编译时知道
Clone::Clone
的具体返回类型,而trait对象
Box
(使用动态分派)不可能这样做。不幸的是,是的。Sequence struct让我可以创建深度嵌套的音乐片段链,程序需要能够处理这些音乐片段。为了我自己的理智,我宁愿复制一个这样的序列,而不是被迫从头开始重新编写
#![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);
}
#![allow(dead_code, unused_macros)]
use std::fmt::Debug;

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

trait MusicElementClone {
    fn clone_box(&self) -> Box<MusicElement>;
}

impl<T: 'static + MusicElement + Clone> MusicElementClone for T {
    fn clone_box(&self) -> Box<MusicElement> {
        Box::new(self.clone())
    }
}

impl Clone for Box<MusicElement> {
    fn clone(&self) -> Box<MusicElement> {
        self.clone_box()
    }
}

#[derive(Debug, Clone)]
struct Note {
    name: String,
    duration: f32,
}

impl MusicElement for Note {
    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: String::from("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);
}
trait MusicElement: Debug + Clone {
    fn duration(&self) -> f32;
}
#[macro_use]
extern crate objekt;

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

clone_trait_object!(MusicElement);

// Everything else as you wrote it.