在 Self 中使用 Rust 解引用运算符 &* vs *? [英] Using Rust dereferencing operators &* vs * with Self?

查看:29
本文介绍了在 Self 中使用 Rust 解引用运算符 &* vs *?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to write an LRU Cache with a memory size limitation rather than the "number of objects" limitation in std. After trying to figure it out for myself, I cheated and looked at an existing implementation, and I almost understand it, but this stops me:

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

这是我不明白的最后一个 unsafe 行.我使用 HashMap 作为底层结构,键与值一起存储,我希望哈希器能够找到它.我将工作哈希键作为对真实键的引用,并提供 HashPartialEq 函数,以便 HashMap 可以找到并使用该键分桶目的.这很容易.

It's that last unsafe line that I don't understand. I'm using a HashMap as the underlying structure, the key is stored with the value, and I want the hasher to be able to find it. I make the working hash key a reference to the real key and provide Hash and PartialEq functions such that the HashMap can find and use the key for bucketing purposes. That's easy.

然后我明白我必须比较 PartialEq 的两个,所以对我来说我必须使用 *self.k 来取消引用当前对象,那么为什么 &*other.k 用于 other 对象?这就是我不明白的.为什么不只是 *other.k?我不是只是取消引用两者以便比较实际的键吗?

I understand then that I have to compare the two for PartialEq, and so it makes sense to me that I have to use *self.k to dereference the current object, so why &*other.k for the other object? That's what I don't understand. Why isn't it just *other.k? Aren't I just dereferencing both so I can compare the actual keys?

推荐答案

我们希望调用 PartialEq::eq:

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

假设 Rhs = SelfSelf = K 的默认实现,我们需要以两种 &K 类型

Assuming the default implementation where Rhs = Self and Self = K, we need to end up with two &K types

  1. other.k*const K
  2. 类型
  3. *other.kK
  4. 类型
  5. &*other.k 属于 &K
  6. 类型
  1. other.k is of type *const K
  2. *other.k is of type K
  3. &*other.k is of type &K

希望这些应该是有意义的.

This much should hopefully make sense.

  1. self.k*const K
  2. 类型
  3. *self.k 属于 K
  4. 类型
  1. self.k is of type *const K
  2. *self.k is of type K

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

The piece that's missing that that method calls are allowed to automatically reference the value they are called on. This is why there's no distinct syntax for a reference and a value, as there would be in C or C++ (foo.bar() vs foo->bar()).

因此,会自动引用 K 以获取 &K,从而实现签名.

Thus, the K is automatically referenced to get &K, fulfilling the signature.

这篇关于在 Self 中使用 Rust 解引用运算符 &amp;* vs *?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆