2

I have the following definition:

pub struct List<T> {
    memory:  Vec<T>,
}

I would get the equivalent of #[derive(PartialEq)] for this type like describe in How can I implement PartialEq?

I use a match expression, like:

impl<T: PartialEq> PartialEq for List<T> {
    fn eq(&self, other: &List<T>) -> bool {
        self.memory == other.memory      
    }
}
impl<T: fmt::Debug> fmt::Debug for List<T> where T:Display {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(write!(f, "["));
        for (count, v) in self.memory.iter().enumerate() {
            if count != 0 { try!(write!(f, ", ")); }
            try!(write!(f, "{}", v));
        }
        write!(f, "]")
    }
}
impl<T> List<T> {
    pub fn new() -> Self {
        List {
            memory: Vec::new(),
        }
    }
    // push() add to end of list
    pub fn push(&mut self, value: T) {
        self.memory.push(value);
    }
}

But the compiler gives me these errors:

error: mismatched types [E0308]

if ! ( * left_val == * right_val ) {

note: in this expansion of assert_eq!

help: run rustc --explain E0308 to see a detailed explanation

note: expected type librusty_data_structures::List<u32>

note: found type [_; 4]

main.rs that produce compile errors

let mut listex: List<u32> = List::new();
listex.push(17);
listex.push(18);
listex.push(19);
listex.push(20);            
assert_eq!(listex, [17, 18, 19, 20]);

I don't understand why that matters. Why is it even looking at that type?

Community
  • 1
  • 1
LeMoussel
  • 5,290
  • 12
  • 69
  • 122
  • That code compiles for me. Can you post the complete file which throws that error? – Dogbert Sep 01 '16 at 07:56
  • updated with main.rs throws that error. – LeMoussel Sep 01 '16 at 08:02
  • Do you want `List` to comparable to `[T; 4]` as well? (Note that you implemented `PartialEq>` for `List` so you can only compare `List` with `List`.) – Dogbert Sep 01 '16 at 08:07
  • I'm new to Rust, what do you mean by `PartialEq>`? – LeMoussel Sep 01 '16 at 08:12
  • `PartialEq` can be implemented for different Lhs (the thing on the left of `==`) and Rhs (the thing on the right of `==`), and if you don't specify `Rhs`, it defaults to `Self`. So with your current implementation, you can only compare `List` with `List` while that `assert_eq!` tries to compare `List` with `[u32; 4]`. – Dogbert Sep 01 '16 at 08:15
  • It would be interesting to know how does `Vec` implement `PartialEq` let mut v = Vec::new(); v.push(1); v.push(2); v.push(3); println!("{}", v == [1, 2, 3]); – LeMoussel Sep 01 '16 at 11:38

2 Answers2

2

listex and [17, 18, 19, 20] have different types (List<u32> and [_; 4]) , so you cannot check for their equality. You need to change the type of one of the arguments of assert_eq!() so the types match. The simplest option would be to reference listex's memory:

assert_eq!(&listex.memory[0..4], [17, 18, 19, 20]);

Or you can convert [17, 18, 19, 20] to a List<u32> so that the PartialEq implementation for List<T> can be put into action.

If you were to compare listex with another List<32>, your PartialEq implementation would allow checks for equality (though you would need the List<T> to derive Debug in order to do perform assert_eq!() on them).

Edit: as for your question "Why is it even looking at that type?", notice that in your implementation of PartialEq:

fn eq(&self, other: &List<T>)

You specify that eq works only for two arguments of type &List<T> (&self points to List<T>).

ljedrz
  • 20,316
  • 4
  • 69
  • 97
2

Here is the solution, following cuviper response on The Rust Programming Language Forum

impl<T, U> PartialEq<U> for List<T>
    where Vec<T>: PartialEq<U>
{
    fn eq(&self, other: &U) -> bool {
        self.memory.eq(other)
    }
}

To test :

let mut listex: List<u32> = List::new();

listex.push(17);
listex.push(18);
listex.push(19);
listex.push(20);            

println!("{}", listex == [17, 18, 19, 20]);
LeMoussel
  • 5,290
  • 12
  • 69
  • 122