为什么 HashMap::get 和 HashMap::entry 采用不同类型的键?

Kod*_*dra 4 generics hashmap rust

的签名HashMap::entry是:

pub fn entry(&mut self, key: K) -> Entry<'_, K, V>
Run Code Online (Sandbox Code Playgroud)

好的,看起来不错。我想从 HashMap 中获取一个条目,其键为K,所以我当然需要给它一个K

然而, 的签名HashMap:get是:

pub fn get<Q>(&self, k: &Q) -> Option<&V>
where
    K: Borrow<Q>,
    Q: Hash + Eq + ?Sized,
Run Code Online (Sandbox Code Playgroud)

现在我完全困惑了。这个复杂的约束是怎么回事?为什么不只是K&K

bk2*_*204 6

当您使用 时entry,您会得到一个空条目或一个已占用条目。如果条目是空的并且您想要调用某些函数,例如or_insert,则需要实际的键,而不是对其的引用,因为此时您将插入到映射中。请注意,我们不知道该密钥支持Copyor Clone,因此我们无法引用并克隆它。

但是,当您使用 时get,您不需要插入实际值。获取引用就可以了,因为您可以仅使用引用来计算HashEq,这是确定键是否在映射中所必需的。如果密钥很大,这会更有效,并且可以避免不必要的分配。

此外,get还允许您使用任何Borrow为密钥实现的东西。因此,如果您的密钥是 a String,则可以使用&strto get。这很好,因为您的密钥可能已被拥有,但您想使用&str文字(例如"foo")在地图中查找。在这种情况下,根本不需要分配,因为字符串是硬编码在程序代码中的。