How to compare two pointers in Rust?

gla*_*gel 1 rust

I want to compare two pointers within the loop:


#[derive(Debug)]
struct Test {
    first: i32,
    second: i32
}

fn main() {
    let test = vec![Test{first:1, second:2}, Test{first:3, second:4}, Test{first:5, second:6}];

    for item in test.iter() {
        println!("---                  {:?}", item);
        println!("item                 {:p}", item);
        println!("test.last().unwrap() {:p}", test.last().unwrap());

        //if item == test.last().unwrap() {
        //    println!("Last item!");
        //}
    }
}
Run Code Online (Sandbox Code Playgroud)

The println gives me both the same addresses

---                  Test { first: 1, second: 2 }
item                 0x563caaf3bb40
test.last().unwrap() 0x563caaf3bb50
---                  Test { first: 3, second: 4 }
item                 0x563caaf3bb48
test.last().unwrap() 0x563caaf3bb50
---                  Test { first: 5, second: 6 }
item                 0x563caaf3bb50
test.last().unwrap() 0x563caaf3bb50
Run Code Online (Sandbox Code Playgroud)

But when I comment in the if-condition, the following error is thrown:

error[E0369]: binary operation `==` cannot be applied to type `&Test`
  --> src/main.rs:20:17
   |
20 |         if item == test.last().unwrap() {
   |            ---- ^^ -------------------- &Test
   |            |
   |            &Test
   |
   = note: an implementation of `std::cmp::PartialEq` might be missing for `&Test`
Run Code Online (Sandbox Code Playgroud)

How can I compare only the two pointers?

rod*_*igo 7

When you compare pointers you are actually comparing the values pointed by those. This is because there are a lot of implementations in std of the type:

impl<'_, '_, A, B> PartialEq<&'_ B> for &'_ A where
    A: PartialEq<B> + ?Sized,
    B: ?Sized,
Run Code Online (Sandbox Code Playgroud)

that do exactly that.

If you want to compare the pointers themselves you can use std::ptr::eq:

pub fn eq<T: ?Sized>(a: *const T, b: *const T) -> bool
Run Code Online (Sandbox Code Playgroud)

Note that even though it takes raw pointers, it is a safe function because it does not dereference the pointers. And since there is an automatic coertion from normal pointer to raw pointer, you can just use:

if std::ptr::eq(item, test.last().unwrap()) {
    println!("Last item!");
}
Run Code Online (Sandbox Code Playgroud)