[英]How to define a Vec in Rust to support containing multiple types of structs that implement a same trait?
In c++, I can define a parent class, and the type in vector can just be the father class type.在 c++ 中,我可以定义一个父 class,向量中的类型可以是父 class 类型。 So how to implement that in Rust?
那么如何在 Rust 中实现呢?
Like for this example:就像这个例子:
I defined two types of Integer who both implement the trait Object, now I want to put them in a same vector, is there any way to achieve that?我定义了两种类型的 Integer,它们都实现了特征 Object,现在我想把它们放在同一个向量中,有什么办法可以实现吗?
pub trait Object<T: Object<T>+Clone> {
fn sub(&self, x: &T) -> T {
x.clone() //this is a useless implementation, just for structs don't need to implement this method.
}
}
#[derive(Debug, Copy, Clone)]
pub struct Integer {
val: i32
}
impl Integer {
pub fn get(&self) -> i32 {
self.val
}
pub fn new(val: i32) -> Self {
Integer {
val
}
}
}
#[derive(Debug, Copy, Clone)]
pub struct Int {
val: i32
}
impl Int {
pub fn get(&self) -> i32 {
self.val
}
pub fn new(val: i32) -> Self {
Int {
val
}
}
}
impl Object<Int> for Int {
fn sub(&self, rhs: &Int) -> Int {
Int {
val: self.val - rhs.get()
}
}
}
impl Object<Integer> for Integer {
fn sub(&self, rhs: &Integer) -> Integer {
Integer {
val: self.val - rhs.get()
}
}
}
fn main() {
let mut v: Vec<Box<dyn Object>> = Vec::new();
v.push(Box::new(Integer::new(1)));
v.push(Box::new(Int::new(2)));
}
Thanks a lot.非常感谢。
There are several aspects of your design that don't fit in Rust:你的设计有几个方面不适合 Rust:
trait Object<T: Object<T>+Clone>
doesn't help - Rust doesn't do CRTP , just use Self
instead. trait Object<T: Object<T>+Clone>
没有帮助 - Rust 不做CRTP ,只用Self
代替。Object
to be object-safe (necessary to put it in a vector), it can't be parameterized by type.Object
是对象安全的(必须将其放入向量中),它不能按类型进行参数化。 A type parameter means you get a completely separate trait for each type.Object::sub()
it can't return values by value - it should return Box<dyn Object>
instead.Object::sub()
它不能按值返回值 - 它应该返回Box<dyn Object>
代替。 The code modified as indicated looks like this:按照指示修改的代码如下所示:
pub trait Object {
fn get(&self) -> i32;
fn sub(&self, x: &dyn Object) -> Box<dyn Object>;
}
#[derive(Debug, Copy, Clone)]
pub struct Integer {
val: i32,
}
impl Integer {
fn new(val: i32) -> Box<dyn Object> {
Box::new(Int {val})
}
}
impl Object for Integer {
fn get(&self) -> i32 {
self.val
}
fn sub(&self, rhs: &dyn Object) -> Box<dyn Object> {
Integer::new(self.val - rhs.get())
}
}
#[derive(Debug, Copy, Clone)]
pub struct Int {
val: i32,
}
impl Int {
fn new(val: i32) -> Box<dyn Object> {
Box::new(Int {val})
}
}
impl Object for Int {
fn get(&self) -> i32 {
self.val
}
fn sub(&self, rhs: &dyn Object) -> Box<dyn Object> {
Int::new(self.val - rhs.get())
}
}
fn main() {
let mut v: Vec<Box<dyn Object>> = Vec::new();
v.push(Integer::new(1));
v.push(Integer::new(2));
v.push(v[0].sub(v[1].as_ref()));
for o in &v {
println!("{}", o.get());
}
}
I think you can combine trait and provide a blank implementation, then use that in vector我认为您可以结合特征并提供一个空白实现,然后在向量中使用它
trait traitA {}
trait traitB {}
trait CombinedTraitATraitB: TraitA + TraitB {}
impl<T> CombinedTraitATraitB for T where T: TraitA + TraitB {}
let vector: Vec<Box<dyn CombinedTraitATraitB>> = vec![];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.