我尝试使用Box和不使用error: cannot convert to a trait object because trait `TraitToImpl` is not object-safe,并且使用和不使用生命周期:

trait TraitToImpl {
    fn do_something(self, val: i32);
}

struct Cont {
    value: i32,
}

impl TraitToImpl for Cont {
    fn do_something(self, val: i32) {
        println!("{}", val);
    }
}

struct StoreTrait<'a> {
    field: Box<TraitToImpl + 'a>,
}

fn main() {
    let cont = Box::new(Cont { value: 12 }) as Box<TraitToImpl>;
    let a = StoreTrait { field: cont };
    a.field.do_something(123);
}

我得到的只是这个错误:

ojit_code

最佳答案

问题是,正如错误消息所说,特征 TraitToImpl 不是对象安全的。也就是说,通过引用(即 &TraitToImplBox<TraitToImpl> )使用该特定特征是不安全的。

具体来说,do_something 方法按值获取 self。考虑:编译器如何在 Cont 中调用这个方法?它必须将值复制到 Box<TraitToImpl> 类型的参数中(这是 Cont 所期望的),但是此调用必须适用于可能实现 impl 的任何大小的任何类型!

实际结果:如果您有一个包含按值 TraitToImpl 或泛型的特征,则不能通过引用使用它。在调用发生时,编译器不再有足够的信息来实际生成必要的代码。

也许尝试改用 self ? :)

关于rust - 是否可以通过特征将值存储在结构中?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27020952/

10-12 04:41