在 Self 中使用 Rust 解引用运算符 &* vs *? [英] Using Rust dereferencing operators &* vs * with Self?
问题描述
我想编写一个具有内存大小限制的 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
作为底层结构,键与值一起存储,我希望哈希器能够找到它.我将工作哈希键作为对真实键的引用,并提供 Hash
和 PartialEq
函数,以便 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
= Self
和 Self
= K
的默认实现,我们需要以两种 &K
类型
Assuming the default implementation where Rhs
= Self
and Self
= K
, we need to end up with two &K
types
other.k
是*const K
类型*other.k
是K
类型&*other.k
属于&K
类型
other.k
is of type*const K
*other.k
is of typeK
&*other.k
is of type&K
希望这些应该是有意义的.
This much should hopefully make sense.
self.k
是*const K
类型*self.k
属于K
类型
self.k
is of type*const K
*self.k
is of typeK
缺少的那部分 允许方法调用自动引用它们被调用的值.这就是为什么引用和值没有明显的语法,就像在 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 解引用运算符 &* vs *?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!