如何在Rust中检查两个HashMap是否相同?

4
我有两个HashMap(playground):
let mut m1: HashMap<u8, usize, _> = HashMap::new();
m1.insert(1, 100);
m1.insert(2, 200);

let mut m2: HashMap<u8, usize, _> = HashMap::new();
m2.insert(2, 200);
m2.insert(1, 100);

如何检查两个映射 m1m2 是否相同?
"相同" 意味着满足以下所有条件。
  • 键的类型相同。

  • 值的类型相同。

  • 两个映射具有完全相同的键集。插入顺序不应该影响结果。

  • 每个键的两个映射都具有完全相同的值(即对于每个现有键 km1.get(k) == m2.get(k))。

据我测试,只需使用 m1 == m2 即可实现此功能。但是,这种行为是否得到保证?我想要某种保证(因此我添加了 #language-lawyer 标签)。
我已经阅读了 HashMap 的官方文档
另外,HashSetVec 呢?(我也阅读了它们的文档。)

查看 HashMap 中使用 == 实现的 PartialEq 的方式可以保证你想要的结果。它会迭代地检查每个映射条目,检查另一个映射是否有该条目,并且值是否相等。 来源 - Bamontan
所以Vec在底层切片上调用eq,它只是遍历整个切片并检查所有值是否相等:来源(如果T是按位可比较的,则有其他实现,因此它可以直接调用memcmp),对于Set,它遍历键并检查另一个集合是否有它:来源 - Bamontan
@Bamontan 谢谢。就你所知,语言设计层面上没有任何保证吗?我的意思是,在 Rust 的未来版本中,如果没有保证,实现(即 rustc)可能会以某种方式进行优化,从而打破当前的比较规则,这种可能性不为零...无论如何,您能否将您的评论发布为答案?非常有帮助。 - ynn
回归是罕见的,几乎不存在。无论稳定版本上有什么,都很可能永远不会出错,尤其是像公共API这样常见的情况。我不知道这些行为是否铭刻在石头上,但我无法想象Rust会对如此广泛使用的稳定功能做出如此重大的更改。 - Bamontan
主要问题是...还有什么其他的语义可以用于比较HashMap,除了“键集相等,每个键对应的值也相等”? - Cerberus
显示剩余2条评论
1个回答

2

浏览std库的源代码,你可以找到不同集合类型的PartialEq实现:

  • HashMap 迭代所有键值对并检查另一个映射是否有相应的键值对,然后检查这些值是否相等:源代码
  • HashSet 迭代所有键并检查另一个集合是否包含该键:源代码
  • Vec 实际上在底层切片上调用eq,它要么遍历每个值并将它们进行比较:源代码,要么如果类型允许,则进行按位比较,通过调用memcmp源代码

我不知道是否有任何保证这种行为永远不会改变,但是由于它们是稳定的、广泛使用的API,我认为它们永远不会改变。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接