Как сравнить два указателя в Rust? - PullRequest
1 голос
/ 11 ноября 2019

Я хочу сравнить два указателя в цикле:


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

println дает мне оба одинаковых адреса

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

Но когда я комментирую в условии if,выдается следующая ошибка:

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`

Как сравнить только два указателя?

1 Ответ

7 голосов
/ 11 ноября 2019

Когда вы сравниваете указатели, вы фактически сравниваете значения, указанные этими. Это потому, что в std имеется множество реализаций типа:

impl<'_, '_, A, B> PartialEq<&'_ B> for &'_ A where
    A: PartialEq<B> + ?Sized,
    B: ?Sized,

, которые делают именно это.

Если вы хотите сравнить сами указатели, вы можете использовать std::ptr::eq:

pub fn eq<T: ?Sized>(a: *const T, b: *const T) -> bool

Обратите внимание, что, хотя он и использует необработанные указатели, это безопасная функция, поскольку она не разыменовывает указатели. А поскольку существует автоматическое приведение от обычного указателя к необработанному указателю, вы можете просто использовать:

if std::ptr::eq(item, test.last().unwrap()) {
    println!("Last item!");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...