【问题标题】:How to check if two reference variable are borrowing the same object? [duplicate]如何检查两个引用变量是否借用了同一个对象? [复制]
【发布时间】:2019-03-22 03:01:05
【问题描述】:

我有一个存储只读引用的结构,例如:

struct Pt { x : f32, y : f32, }
struct Tr<'a> { a : &'a Pt }

我想impl EqTr 测试底层a 是否引用完全相同的Pt

let trBase1 = Pt::new(0.0, 0.0);
let trBase2 = Pt::new(0.0, 0.0);
assert!(trBase1 == trBase2);        // ok.
let tr1 = Tr::new(&trBase1);
let tr2 = Tr::new(&trBase2);
let tr3 = Tr::new(&trBase1);
assert!(tr1 == tr3);                // ok.
assert!(tr1.a == te2.a);            // ok. Using Eq for Pt that compare values.
assert!(tr1 != tr2);                // panicked! Not intended.

所以现在我有

impl<'a> PartialEq for Tr<'a> {
    fn eq(&self, v : &Tr<'a>) -> bool {
        // self.a == v.a // doesn't work.
    }
}

我应该写什么?

【问题讨论】:

    标签: rust borrowing


    【解决方案1】:

    您可以使用std::ptr::eq 来比较两个指针的地址。如果提供给此函数,引用(&amp;T&amp;mut T)将自动强制转换为基础指针(*const T)。当然,可变引用与另一个引用具有相同的地址是没有意义的,因为可变引用总是独占引用,但它仍然可以强制为*const T

    // This derive will use the equality of the underlying fields
    #[derive(PartialEq)]
    struct Pt {
        x: f32,
        y: f32,
    }
    
    impl Pt {
        fn new(x: f32, y: f32) -> Self {
            Self { x, y }
        }
    }
    
    struct Tr<'a> {
        a: &'a Pt,
    }
    
    impl<'a> Tr<'a> {
        fn new(a: &'a Pt) -> Self {
            Self { a }
        }
    }
    
    // Here we use std::ptr::eq to compare the *addresses* of `self.a` and `other.a`
    impl<'a> PartialEq for Tr<'a> {
        fn eq(&self, other: &Tr<'a>) -> bool {
            std::ptr::eq(self.a, other.a)
        }
    }
    
    fn main() {
        let tr_base1 = Pt::new(0.0, 0.0);
        let tr_base2 = Pt::new(0.0, 0.0);
        assert!(tr_base1 == tr_base2);
    
        let tr1 = Tr::new(&tr_base1);
        let tr2 = Tr::new(&tr_base2);
        let tr3 = Tr::new(&tr_base1);
    
        assert!(tr1 == tr3);
        assert!(tr1.a == tr2.a);
        assert!(tr1 != tr2);
    }
    

    (playground link)

    【讨论】:

      【解决方案2】:

      将引用转换为原始指针并进行比较。

      impl<'a> PartialEq for Tr<'a> {
          fn eq(&self, v: &Tr<'a>) -> bool {
              self.a as *const _ == v.a as *const _
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2021-02-26
        • 1970-01-01
        • 1970-01-01
        • 2012-06-30
        • 2014-09-07
        • 2017-01-20
        • 2012-11-21
        • 2011-11-11
        • 2014-03-25
        相关资源
        最近更新 更多