简体   繁体   English

具有 PartialEq 依赖关系的共享特征的对象向量

[英]Vector of objects sharing a trait with PartialEq dependency

I'm trying to make a vector that would store objects of different structs that implement a certain trait , however, I really want my trait to be a supertrait of Eq (and thus PartialEq ).我正在尝试创建一个vector来存储实现某个trait的不同结构的对象,但是,我真的希望我的 trait 成为Eq的超特征(因此PartialEq )。

The Book provides a way to do that with Vec<Box<dyn Draw>> , however, the PartialEq dependency seems to disallow this approach with the trait cannot be made into an object error. 这本书提供了一种使用Vec<Box<dyn Draw>>的方法,但是, PartialEq依赖项似乎不允许这种方法,因为该特征不能成为 object错误。

This answer provides a way to do a similar thing for HashMap s.这个答案提供了一种对HashMap做类似事情的方法。 However, this approach seems too verbose for what I am trying to achieve.但是,对于我想要实现的目标,这种方法似乎过于冗长。

What would be the idiomatic way to have a vector for structs implementing such a trait?为实现这种特征的结构提供向量的惯用方式是什么?

Code to reproduce below and on the playground在操场下面和操场上重现的代码

pub trait MyTrait: PartialEq { fn my_func() -> bool; }

pub struct Struct1 { age: i32 }

impl PartialEq<Self> for Struct1 {
    fn eq(&self, other: &Self) -> bool { self.age == other.age }
}

impl MyTrait for Struct1 {
    fn my_func() -> bool { false }
}
pub struct Struct2 { year: i32 }

impl PartialEq<Self> for Struct2 {
    fn eq(&self, other: &Self) -> bool { self.year == other.year }
}

impl MyTrait for Struct2 {
    fn my_func() -> bool { true }
}

fn main() {
    let mut v: Vec<Box<dyn MyTrait>> = Vec::new();
    // v.push(Struct1 { age: 1 });
    // v.push(Struct2 { year: 2 });
}

Depending on your actual use case, this may or may not work for you, but from the info in your question and comment, I wouldn't go the trait object route but rather the enum route.根据您的实际用例,这可能对您有用,也可能不适用,但从您的问题和评论中的信息来看,我不会 go 特征 object 路线而是枚举路线。 Have all the types you want to store as variants on an enum, for example like this:将所有要作为变体存储在枚举中的类型,例如:

pub trait MyTrait: PartialEq { fn my_func(&self) -> bool; }

pub enum Struct {
    Struct1 {
        age: i32,
    },
    Struct2 {
        year: i32,
    }
}

impl PartialEq<Self> for Struct {
    fn eq(&self, other: &Self) -> bool {
        use Struct::*;
        match (self, other) {
            (Struct1 { age: age1 }, Struct1 { age: age2 }) => age1 == age2,
            (Struct2 { year: year1 }, Struct2 { year: year2 }) => year1 == year2,
            _ => false
        }
    }
}

impl MyTrait for Struct {
    fn my_func(&self) -> bool {
        use Struct::*;
        match self {
            Struct1 { .. } => false,
            Struct2 { .. } => true,
        }
    }
}

fn main() {
    let mut v: Vec<Struct> = Vec::new();
    v.push(Struct::Struct1 { age: 1 });
    v.push(Struct::Struct2 { year: 2 });
    assert!(v.contains(&Struct::Struct2 { year: 2 }));
}

Feel free to let me know if there are more constraints that would make this approach infeasible.如果有更多限制会使这种方法不可行,请随时告诉我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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