rust - 创建特征对象的副本

标签 rust

如何创建特征对象的副本以进行本地计算?

问题是我想要一个函数,它接受对特征对象的可变引用,以便进行一些计算并根据这些计算对其进行修改,但在计算过程中,该函数必须临时修改特征对象并在本地使用其修改后的版本进行计算。

我尝试了以下方法(及其变体):

struct Data {
    fields: Vec<f32>
}

trait CustomCollection {
    fn get_mut(&mut self) -> &mut [f32];
}

impl CustomCollection for Data {
    fn get_mut(&mut self) -> &mut [f32] {
    return &mut self.fields;
    }
}

fn copy(s: &mut dyn CustomCollection) {
    let c: Box::<dyn CustomCollection> = Box::new(*s);
}

fn main() {
    let mut d = Data{fields: vec![1f32, 2.0, 3.0]};
    copy(&mut d);
}

但我收到错误:

error[E0277]: the size for values of type `dyn CustomCollection` cannot be known at compilation time
  --> src/test.rs:16:51
   |
16 |     let c: Box::<dyn CustomCollection> = Box::new(*s);
   |                                          -------- ^^ doesn't have a size known at compile-time
   |                                          |
   |                                          required by a bound introduced by this call
   |
   = help: the trait `Sized` is not implemented for `dyn CustomCollection`
note: required by a bound in `Box::<T>::new`
  --> /rustc/fc594f15669680fa70d255faec3ca3fb507c3405/library/alloc/src/boxed.rs:204:6
   |
   = note: required by this bound in `Box::<T>::new`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.

最佳答案

您可以使用clone来扩展您想要构建特征对象的特征。或copy返回 Box<dyn CustomCollection> 的方法。例如这样:

#[derive(Clone)]
struct Data {
    fields: Vec<f32>
}

trait CustomCollection {
    fn get_mut(&mut self) -> &mut [f32];
    
    fn clone_box(&self) -> Box<dyn CustomCollection>;
}

impl CustomCollection for Data {
    fn get_mut(&mut self) -> &mut [f32] {
        &mut self.fields
    }
    
    fn clone_box(&self) -> Box<dyn CustomCollection> {
        Box::new(<Self as Clone>::clone(self))
    }
}

fn copy(s: &mut dyn CustomCollection) -> Box<dyn CustomCollection> {
    s.clone_box()
}

fn main() {
    let mut d = Data{fields: vec![1f32, 2.0, 3.0]};
    copy(&mut d);
}

Playground.


@prog-fh 非常友善和尖锐 this answer out,其中包含我在示例中尝试完成的任务的更灵活的实现。还有 dyn-clone @dtolnay 的 crate 随时可供您使用,因此您不必自己实现克隆特征对象。

关于rust - 创建特征对象的副本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75564384/

相关文章:

rust - Substrate - 在此范围内找不到类型 `Vec`

generics - 有没有一种安全的方法可以为函数的不可变和可变变体重用相同的代码?

recursion - 有没有办法优化这段代码,使其不会溢出堆栈?

lambda - 为什么这个闭包需要内联或 `dyn` ? `dyn` 在这里做什么?

c - 如何为包含可空函数指针的 FFI 创建结构?

rust - 模式匹配解析 float 错误

rust - 有条件地迭代几个可能的迭代器之一

rust - 处理由 C FFI 强制执行的有问题的父子关系

iterator - 如何在切片上返回迭代器?

rust - Serde 能否根据字段的值将 JSON 反序列化为一组类型中的一种?