使用Rust解除引用运算符&*vs*with Self?

Elf*_*erg 2 rust

我想编写一个具有内存大小限制的LRU缓存,而不是std中的"对象数量"限制.在试图为自己弄清楚之后,我作弊并查看了现有的实现,我几乎理解它,但这阻止了我:

struct KeyRef<K> {
    k: *const K,
}

impl<K: Hash> Hash for LruKeyRef<K> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        unsafe { (*self.k).hash(state) }
    }
}

impl<K: PartialEq> PartialEq for LruKeyRef<K> {
    fn eq(&self, other: &LruKeyRef<K>) -> bool {
        unsafe { (*self.k).eq(&*other.k) }
    }
}
Run Code Online (Sandbox Code Playgroud)

这unsafe是我不明白的最后一行.我使用a HashMap作为底层结构,密钥与值一起存储,我希望hasher能够找到它.我将工作哈希键作为对真实密钥的引用,并提供Hash和PartialEq功能,以便HashMap可以找到并使用密钥进行分组.这很简单.

我知道那个时候,我要比较两个的PartialEq,所以它是有道理的,我认为我必须使用*self.k取消引用当前对象,那么为什么&*other.k对于其他对象?这就是我不明白的地方.为什么不呢*other.k?我不是只是解除引用两者所以我可以比较实际的密钥吗?

She*_*ter 6

我们希望致电PartialEq::eq:

trait PartialEq<Rhs = Self>
where
    Rhs: ?Sized,
{
    fn eq(&self, other: &Rhs) -> bool;
}
Run Code Online (Sandbox Code Playgroud)

假设默认实现where Rhs= Self和Self= K,我们需要最终得到两种&K类型

  1. other.k 是类型的 *const K
  2. *other.k 是类型的 K
  3. &*other.k 是类型的 &K

这很有道理.

  1. self.k 是类型的 *const K
  2. *self.k 是类型的 K

缺少该方法调用的部分允许自动引用它们被调用的值.这就是为什么引用和值没有明确的语法,就像在C或C++(foo.bar()vs foo->bar())中一样.

因此,K自动引用以获得&K,实现签名.