Rust 是否可以通过trait在结构中存储值?

Rust 是否可以通过trait在结构中存储值?,rust,traits,lifetime,Rust,Traits,Lifetime,编者注:此代码示例来自Rust 1.0之前的版本,在语法上不是有效的Rust 1.0代码。此代码的更新版本会产生不同的错误,但答案仍然包含有价值的信息 我尝试了使用和不使用框,使用和不使用寿命: trait TraitToImpl { fn do_something(self, val: i32); } struct Cont { value: i32, } impl TraitToImpl for Cont { fn do_something(self, val:

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

我尝试了使用和不使用
,使用和不使用寿命:

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{
fn做某事(self,val:i32);
}
结构控制{
值:i32,
}
impl TraitToImpl for Cont{
fn做某事(self,val:i32){
println!(“{}”,val);
}
}
struct StoreTrait,
}
fn main(){
让cont=Box::new(cont{value:12})作为Box;
设a=StoreTrait{field:cont};
a、 字段。做某事(123);
}
我得到的只是这个错误:


错误:无法转换为trait对象,因为trait`traitImpl`不是对象安全的

正如错误消息所述,问题在于trait
traitImpl
不是对象安全的。也就是说,通过引用(即
&traitImpl
)使用该特定特征是不安全的

具体来说,
dou\u something
方法按值获取
self
。考虑:编译器如何对放置在
框中的
Cont
调用此方法?它必须将值复制到
Cont
类型的参数中(这是
impl
所期望的),但此调用必须适用于可能实现
traitImpl
的任何大小的任何类型

实际结果:如果你有一个trait包含by value
self
,或者泛型,它不能通过引用来使用。在调用发生时,编译器不再有足够的信息来实际生成必要的代码


可能尝试使用
&self
代替?:)

要了解此错误的来源,还可以在以下列表中查找对象安全的定义:

如果调用
x.m(…)
是合法的(在当前的情况下),
x
具有类型
&T
,也就是说,
x
是特征对象,那么我们说trait
T
上的
m
方法是对象安全的。如果
T
中的所有方法都是对象安全的,那么我们说
T
是对象安全的

正如@DK所指出的,
x.do\u something(…)
是非法的,因为
TraitToImpl
不能按值传递

注意,从非对象安全特性派生也可能违反对象安全性。例如

trait TraitToImpl : Clone {
    fn do_something(&self, val: int); // this method is object-safe
}

不会是对象安全的,因为
Clone
本身有一个非对象安全的方法(
fn Clone(&self)->self
)。

非常感谢。我不清楚这个错误信息。而且,如果我理解正确,就不可能通过特质传递价值。