为特定变体派生特征

问题描述 投票:0回答:2

假设我有以下枚举

enum MyEnum {
  VariantA,
  VariantB,
  VariantC,
}

我可以通过这样做来获得整个枚举的PartialEq特征

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

我想要做的是推导出特质,但仅限于特定的变体,而不是整个枚举。那可能吗? (或者它甚至有意义吗?)。

enums rust traits
2个回答
2
投票

我想要做的是推导出特质,但仅限于特定的变体,而不是整个枚举。那可能吗? (或者它甚至有意义吗?)。

这没有多大意义。

特征是针对类型实现的。枚举是一种类型,其变体是它的值。你的问题等同于询问你是否可以为某些Strings而不是其他人实施特征。

如果不受支持的变体可以接受总是返回false,类似于f32PartialEq实现在每次比较false值时返回NaN,那么你可以手工编写impl:

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,
        }
    }
}

请注意,您不能以这种方式实现Eq,因为Eq的实现可能被假定为total,而事实并非如此。


2
投票

假设你有一个像这样的设置:

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

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

VarA来自不同的包,由于没有派生PartialEq(或任何其他外部特征),您无法编译。

您可以使用newtype模式解决这个问题(假设您可以访问相关字段/访问者)

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

进一步的信息:https://doc.rust-lang.org/rust-by-example/generics/new_types.html

© www.soinside.com 2019 - 2024. All rights reserved.