简体   繁体   中英

Checking equality of custom structs

I'm trying to check equality of two (functionally identical) structs.

#[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"));
}

It returns the error:

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

It seems like deriving PartialEq isn't working. Is the only solution to implement it manually between these two types? Is the problem somewhere else entirely?

Deriving PartialEq does work; but Rust does not have a notion of structural equality of different types. If you write #[derive(PartialEq)] on one type, it does not mean that values of this type could be compared with values of another type, even if it has the same internal structure. It only means that values of this type can be compared between themselves.

However, PartialEq has a type parameter for the right-hand side operand (creatively named Rhs ), which means you can implement PartialEq multiple times for a single type with different type arguments. #[derive(PartialEq)] will only implement PartialEq<X> when applied on X , but that doesn't stop you from implementing PartialEq<Y> for other values of Y yourself.

In this case, you do need to implement PartialEq manually for these types, in both directions:

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

Afterwards you will be able to use == or assert_eq!() for these pairs of types. Remember that you can still keep #[derive(PartialEq)] on your types if you need it too!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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