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

标签 rust traits lifetime

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不是对象安全的。也就是说,通过引用(即 &TraitToImplBox<TraitToImpl> )使用该特定特征是不安全

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

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

也许尝试服用 &self反而? :)

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

相关文章:

rust - 如何检查一个值是否有效然后返回它?

generics - 是否可以在 Vec 中存储类型而不是这些类型的实例?

rust - Rust 对临时值的不可变和可变引用是如何删除的?

arrays - 如何在 Rust 中执行高效的向量初始化?

generics - 可变借位在循环的上一迭代中从此处开始

scala - 如何使用在 Scala 中创建数据集的通用案例类实现特征

generics - 在不固定 `Fn` 参数之一的情况下,在结构定义上指定 `Fn` trait bound

scala:定义特征并引用相应的伴生对象

rust - 如何为创建具有特征生命周期限制的对象的生产者查找通用范围

reference - 有什么方法可以返回对在函数中创建的变量的引用?