是否可以通过特征在结构中存储值?

Ser*_*zko 6 traits lifetime rust

编者注:此代码示例来自1.0之前的Rust版本,并且在语法上不是有效的Rust 1.0代码.此代码的更新版本会产生不同的错误,但答案仍包含有价值的信息.

无论Box有没有生命,我都试过这个:

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);
}
Run Code Online (Sandbox Code Playgroud)

我得到的只是这个错误:

error: cannot convert to a trait object because trait `TraitToImpl` is not object-safe

DK.*_*DK. 8

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

具体而言,该do_something方法self取值.考虑一下:编译器如何调用这个方法Cont放在一个Box<TraitToImpl>?它必须将值复制到类型的参数中Cont(这是impl预期的),但是这个调用必须适用于任何可能实现的任何大小的类型TraitToImpl!

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

也许尝试一下&self呢?:)