繁体   English   中英

如何在 Rust 中定义 Vec 以支持包含实现相同特征的多种类型的结构?

[英]How to define a Vec in Rust to support containing multiple types of structs that implement a same trait?

在 c++ 中,我可以定义一个父 class,向量中的类型可以是父 class 类型。 那么如何在 Rust 中实现呢?

就像这个例子:

我定义了两种类型的 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)));
}

非常感谢。

你的设计有几个方面不适合 Rust:

  • trait Object<T: Object<T>+Clone>没有帮助 - Rust 不做CRTP ,只用Self代替。
  • 对于Object对象安全的(必须将其放入向量中),它不能按类型进行参数化。 类型参数意味着您可以为每种类型获得完全独立的特征。
  • 出于同样的原因, Object::sub()它不能按值返回值 - 它应该返回Box<dyn Object>代替。

按照指示修改的代码如下所示:

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());
    }
}

操场

我认为您可以结合特征并提供一个空白实现,然后在向量中使用它

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM