Editor's note: This code example is from a version of Rust prior to 1.0 and is not syntactically valid Rust 1.0 code. Updated versions of this code produce different errors, but the answers still contain valuable information.
我试过使用和不使用 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);
}
我得到的只是这个错误:
错误:无法转换为特征对象,因为特征 `TraitToImpl` 不是对象安全的
最佳答案
问题是,正如错误消息所说,特征 TraitToImpl
不是对象安全的。也就是说,通过引用(即 &TraitToImpl
或 Box<TraitToImpl>
)使用该特定特征是不安全。
具体来说,do_something
方法需要 self
按值(value)。考虑:编译器如何在 Cont
上调用这个方法它被放置在 Box<TraitToImpl>
中?它必须将值复制到 Cont
类型的参数中(这是 impl
所期望的),但此调用必须适用于可能实现 TraitToImpl
的任何类型的任何大小 !
实际结果:如果你有一个包含按值 self
的特征,或泛型,它不能通过引用使用。在调用发生时,编译器不再具有足够的信息来实际生成必要的代码。
也许尝试服用 &self
反而? :)
关于rust - 是否可以通过特征将值存储在结构中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27020952/