Derive a Trait for particular variants

泪湿孤枕 提交于 2019-12-02 03:32:01

问题


Let's say I have the following Enum

enum MyEnum {
  VariantA,
  VariantB,
  VariantC,
}

I can derive the PartialEq trait for the whole enum by doing so

#[derive(PartialEq)]
enum MyEnum {
  VariantA,
  VariantB,
  VariantC,
}

What I want to do, is derive the trait but only to particular variants and not the whole enum. Is that possible? (or does it even make sense?).


回答1:


Assuming you have a setup like:

#[derive(PartialEq)]
struct VarB{
    pub value: u32,
}

#[derive(PartialEq)]
enum MyEnum{
    VarA(VarA),
    VarB(VarB)
}

VarA comes from a different crate and you can't compile due to it not having derived PartialEq (or any other external trait).

You can solve that with the newtype pattern (assuming you have access to the relevent fields / accessors)

struct MyVarA(VarA);

impl PartialEq for MyVarA{
    fn eq(&self, other: &MyVarA) -> bool {
        self.0.value == other.0.value
    }

    fn ne(&self, other: &MyVarA) -> bool {
        self.0.value != other.0.value
    }
}

#[derive(PartialEq)]
struct VarB{
    value: u32,
}

#[derive(PartialEq)]
enum MyEnum{
    VarA(MyVarA),
    VarB(VarB)
}

further informations: https://doc.rust-lang.org/rust-by-example/generics/new_types.html




回答2:


What I want to do, is derive the trait but only to particular variants and not the whole enum. Is that possible? (or does it even make sense?).

This doesn't really make sense.

Traits are implemented for types. An enum is a type and its variants are its values. Your question is equivalent to asking if you could implement a trait for some Strings but not others.

If it is acceptable for unsupported variants to always return false, similar to how f32's PartialEq implementation returns false whenever you compare a NaN value, then you can write that impl by hand:

impl PartialEq for MyEnum {
    fn eq(&self, other: &MyEnum) -> bool {
        use MyEnum::*;
        match (self, other) {
            // VariantA and VariantB are supported
            (VariantA(value), VariantA(other_value)) => value == other_value,
            (VariantB(value), VariantB(other_value)) => value == other_value,
            // Any other combinations of variants end up here
            _ => false,
        }
    }
}

Note that you must not implement Eq this way, since implementations of Eq may be assumed to be total, which this is not.



来源:https://stackoverflow.com/questions/55011280/derive-a-trait-for-particular-variants

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!