String
和 str
都实现了 Hash
接口,因此我们可以对它们进行哈希。看起来,目前所有的拥有和借用字符串都哈希到了相同的值,因此这个断言是成立的:
use std::hash::Hash;
use std::hash::Hasher;
use std::collections::hash_map::DefaultHasher;
pub fn main() {
let hash1 = {
let x: String = "abc".to_owned();
let mut hasher = DefaultHasher::new();
x.hash(&mut hasher);
hasher.finish()
};
let hash2 = {
let x: &str = "abc";
let mut hasher = DefaultHasher::new();
x.hash(&mut hasher);
hasher.finish()
};
assert!(hash1 == hash2);
}
我正在编写代码,利用
HashMap
的 raw_entry
API 中的这种行为。具体来说,我正在使用一个 HashMap,其中键是枚举类型,但为了减少重复分配内存,我想要使用这些枚举类型的“borrowed”版本进行查找。换句话说,在下面的代码中,我需要确保两个断言都成功,而不管使用哪个实现的
Hasher
。 我觉得这取决于 String
和 str
的 Hash
实现提供的保证。use std::hash::Hash;
use std::hash::Hasher;
use std::collections::hash_map::DefaultHasher;
pub fn main() {
{
#[derive(Hash)]
enum E1 {
First(i32),
Second(String),
}
#[derive(Hash)]
enum E2<'a> {
First(i32),
Second(&'a str),
}
let hash1 = {
let x: E1 = E1::First(100);
let mut hasher = DefaultHasher::new();
x.hash(&mut hasher);
hasher.finish()
};
let hash2 = {
let x: E2 = E2::First(100);
let mut hasher = DefaultHasher::new();
x.hash(&mut hasher);
hasher.finish()
};
assert!(hash1 == hash2);
let hash3 = {
let x: E1 = E1::Second("abc".to_owned());
let mut hasher = DefaultHasher::new();
x.hash(&mut hasher);
hasher.finish()
};
let hash4 = {
let x: E2 = E2::Second("abc");
let mut hasher = DefaultHasher::new();
x.hash(&mut hasher);
hasher.finish()
};
assert!(hash3 == hash4);
}
}
有没有关于这种保证的文档记录?我认为必须提供这样的保证(否则我看不到正确实现HashMap
的contains_key()
方法的方法,因为参数可以是任何借用的键形式),但我找不到任何文档记录这种保证。