HashMap::entry
的签名是:
pub fn entry(&mut self, key: K) -> Entry<'_, K, V>
好的,看起来不错。我想从 HashMap 中获取一个键为
K
的条目,所以我当然需要给它一个 K
。
然而,
HashMap:get
的签名是:
pub fn get<Q>(&self, k: &Q) -> Option<&V>
where
K: Borrow<Q>,
Q: Hash + Eq + ?Sized,
现在我完全困惑了。这个复杂的约束是怎么回事?为什么不只是
K
或 &K
?
当您使用
entry
时,您会得到一个空条目或一个已占用条目。如果条目是空的,并且您想调用某些函数,例如 or_insert
,则需要实际的键,而不是对其的引用,因为此时您将插入到地图中。请注意,我们不知道该密钥支持 Copy
或 Clone
,因此我们无法引用并克隆它。
但是,当您使用
get
时,您不需要插入实际值。获取参考就可以了,因为您可以仅使用参考来计算 Hash
和 Eq
,这是确定密钥是否在地图中所必需的。如果密钥很大,这会更有效,并且可以避免不必要的分配。
此外,
get
还允许您使用任何实现Borrow
作为密钥的东西。因此,如果您的密钥是 String
,您可以使用 &str
到 get
。这很好,因为您的密钥可能已被拥有,但您想使用 &str
文字(如 "foo"
)在地图中查找。在这种情况下,根本不需要分配,因为字符串是硬编码在程序代码中的。