Rust Can';t克隆向量<;盒子<;特质>&燃气轮机;因为特质不能被制造成一个物体
我想克隆一个盒状特征的载体。 当然,仅仅在实现my trait的所有结构上派生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持
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”`
这里有一个简单的代码运行方法
我还尝试将序列中的元素
向量
aVec
,但也没有成功
我还没有在网上找到任何有用的解决方案,所以我的问题是:如何使代码可克隆?解决方案在于结合到目前为止评论中的建议-中的答案告诉您必须为所有兼容(
'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.