Pointers 将实现特征的数据存储在向量中
一般来说,我对Rust和系统语言非常陌生。我现在正在和Rust一起探索语言。我有一个我自己无法解决的问题。我想我已经明白了问题所在 我不想将实现Pointers 将实现特征的数据存储在向量中,pointers,vector,rust,traits,lifetime,Pointers,Vector,Rust,Traits,Lifetime,一般来说,我对Rust和系统语言非常陌生。我现在正在和Rust一起探索语言。我有一个我自己无法解决的问题。我想我已经明白了问题所在 我不想将实现trait BaseStuff的对象存储在向量中。对我来说,这不是一项简单的任务:-) 下面是我的示例代码,它不会编译 trait BaseStuff {} struct MyStuff { value: i32, } struct AwesomeStuff { value: f32, text: String, } imp
trait BaseStuff
的对象存储在向量中。对我来说,这不是一项简单的任务:-)
下面是我的示例代码,它不会编译
trait BaseStuff {}
struct MyStuff {
value: i32,
}
struct AwesomeStuff {
value: f32,
text: String,
}
impl BaseStuff for MyStuff {}
impl BaseStuff for AwesomeStuff {}
struct Holder {
stuff: Vec<BaseStuff>,
}
impl Holder {
fn register(&mut self, data: impl BaseStuff) {
self.stuff.push(data);
}
}
fn main() {
let my_stuff = MyStuff { value: 100 };
let awesome_stuff = AwesomeStuff {
value: 100.0,
text: String::from("I'm so awesome!"),
};
let mut holder = Holder { stuff: vec![] };
holder.register(my_stuff);
}
现在我遇到了一个新的编译器问题:
错误[E0310]:参数类型impl BaseStuff
可能无法长期使用
足够-->src\main.rs:22:25 | 21 | fn寄存器(&mut self),
数据:impl BaseStuff){|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |^^^^^^^^^^^^^^^^^^注:…以便 类型
impl BaseStuff
将满足其所需的生存期限制-->
src\main.rs:22:25 | 22 | self.stuff.push(Box::new(data));|^^^^^^^^^^^^^^ 错误:由于上一个错误而中止 有关此错误的详细信息,请尝试
rustc--explain E0310
。
错误:无法编译
我知道我出局了……我在书中读到了关于生命的内容,并在这里用'a
和'a
以任何组合更改了我的代码,但没有运气……我不想写下我尝试过的任何生命定义组合。
我不明白为什么我需要生命周期定义。所有权在任何步骤中都会被移动,因此我很清楚Holder struct是所有数据的所有者。是吗
如何更正代码以进行编译
谢谢您的帮助。您几乎可以得到它-这里的问题是BaseStuff
实现的类型可能是一个引用(例如impl BaseStuff for&SomeType
)。这意味着,即使您按值传递数据,该值也可能是一个在框中过期的引用
解决这一问题的方法是添加一个约束,使对象具有一个静态
生存期,这意味着它将是一个值类型或静态引用。根据您的用例,您可以将此约束应用于trait或接受trait的方法
将约束应用于特征:
trait-BaseStuff:'static{}
将约束应用于方法:
impl支架{
fn寄存器(&mut self,数据:impl BaseStuff+'静态){
self.stuff.push(Box::new(data));
}
}
如果将静态
约束添加到方法中,我建议也将其添加到Vec
中,以避免丢失类型信息,如下所示:
struct Holder{
stuff:vec简单地说,这也会起作用:data:impl-BaseStuff+'static
。但问题是为什么vec.push需要静态生存期。data
必须已经移动了?ÖmerErden静态生存期是必需的,因为添加到向量中的数据本身可能是一个引用。BaseStuff
可以为任何类型-例如,impl BaseStuff for&SomeType
将允许您将类似于&SomeType
的引用传递给该方法。这将触发生存期检查,因为引用本身存储在框中,而不是引用引用的值。哦,我应该先检查解释,谢谢。但我会请参阅将装箱数据发送到holder,但如果我将某一类型的引用装箱,然后将其发送到push,会发生什么情况?@ÖmerErden您能给我一个示例说明您的意思吗?装箱引用(Box
)这似乎是一个奇怪的用例,但如果引用有一个“静态”
生存期,它应该可以工作,否则就会失败。如果没有静态生存期,您可以通过只使用装箱的BaseStuff来解决此问题:fn register(&mut self,data:Box)
,请检查。
struct Holder {
stuff: Vec<Box<BaseStuff>>,
}
impl Holder {
fn register(&mut self, data: impl BaseStuff) {
self.stuff.push(Box::new(data));
}
}