Получите черту для определенных вариантов - PullRequest
0 голосов
/ 05 марта 2019

Допустим, у меня есть следующее Enum

enum MyEnum {
  VariantA,
  VariantB,
  VariantC,
}

Я могу вывести черту PartialEq для всего перечисления, выполнив так:

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

Что я хочу сделать, это получитьчерта, но только к конкретным вариантам, а не всему перечислению.Это возможно?(или это вообще имеет смысл?).

Ответы [ 2 ]

2 голосов
/ 06 марта 2019

При условии, что у вас есть настройки как:

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

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

VarA происходит из другого ящика, и вы не можете скомпилировать его, так как он не имеет PartialEq (или любой другой внешней черты).

Вы можете решить это с помощью шаблона нового типа (при условии, что у вас есть доступ к соответствующим полям / методам доступа)

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 / ржавчины на примерах / генерики / new_types.html

2 голосов
/ 06 марта 2019

Что я хочу сделать, это получить черту, но только для определенных вариантов, а не для всего перечисления.Это возможно?(или это вообще имеет смысл?).

Это на самом деле не имеет смысла.

Черты реализованы для типов .Перечисление - это тип, а его варианты - его значения.Ваш вопрос эквивалентен вопросу о том, можете ли вы реализовать черту для некоторых String с, но не для других.

Если для неподдерживаемых вариантов допустимо всегда возвращать false, аналогично тому, как f32PartialEq реализация возвращает false всякий раз, когда вы сравниваете значение NaN, тогда вы можете написать это значение вручную:

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 , что не является.

...