检查自定义结构的相等性

时间:2016-02-02 18:29:05

标签: rust

我试图检查两个(功能相同)结构的相等性。

#[derive(PartialEq, Debug)]
pub struct TypeA<'a>(&'a str);

#[derive(PartialEq, Debug)]
pub struct TypeB<'a>(&'a str);

impl<'a> TypeA<'a> {
    pub fn new(n: &str) -> TypeA {
        TypeA(n)
    }
}

impl<'a> TypeB<'a> {
    pub fn new(n: &str) -> TypeB {
        TypeB(n)
    }
}

fn main() {
    assert_eq!(TypeA::new("A"), TypeB::new("A"));
}

它返回错误:

error[E0308]: mismatched types
  --> src/main.rs:20:5
   |
20 |     assert_eq!(TypeA::new("A"), TypeB::new("A"));
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `TypeA`, found struct `TypeB`
   |
   = note: expected type `TypeA<'_>`
              found type `TypeB<'_>`
   = note: this error originates in a macro outside of the current crate

似乎导出PartialEq并不起作用。是在这两种类型之间手动实现它的唯一解决方案吗?问题完全在其他地方吗?

1 个答案:

答案 0 :(得分:13)

派生PartialEq确实有效;但Rust没有不同类型结构平等的概念。如果在一种类型上编写#[derive(PartialEq)],则并不意味着可以将此类型的值与另一种类型的值进行比较,即使它具有相同的内部结构。它只意味着可以在它们之间比较这种类型的值。

但是,PartialEq具有右侧操作数的类型参数(创造性地命名为Rhs),这意味着您可以针对具有不同类型的单个类型多次实现PartialEq参数。 #[derive(PartialEq)]仅在PartialEq<X>上应用时才会实施X,但这不会阻止您自己为PartialEq<Y>的其他值实施Y

在这种情况下,您需要在两个方向上手动为这些类型实施PartialEq

impl<'a, 'b> PartialEq<TypeB<'b>> for TypeA<'a> {
    fn eq(&self, other: &TypeB<'b>) -> bool {
        self.0 == other.0
    }
}

impl<'a, 'b> PartialEq<TypeA<'a>> for TypeB<'b> {
    fn eq(&self, other: &TypeA<'a>) -> bool {
        self.0 == other.0
    }
}

之后,您可以使用==assert_eq!()来表示这些类型。请记住,如果您需要,您仍然可以保留#[derive(PartialEq)]类型!