Hash 拥有和借用的字符串是否保证散列为相同的值?
Hash 拥有和借用的字符串是否保证散列为相同的值?,hash,rust,hashmap,Hash,Rust,Hashmap,String和str都实现了Hash,因此我们可以对它们进行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 m
String
和str
都实现了Hash
,因此我们可以对它们进行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\u条目
API中编写利用这种行为的代码。具体来说,我使用的是一个HashMap,其中键是枚举,但为了减少冗余分配,我希望使用这些枚举的“借用”版本进行查找
换句话说,在下面的代码中,我确实需要保证两个断言都会成功,而不管使用的是Hasher
实现。在我看来,这取决于Hash
实现String
和str
提供的保证
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);
}
}
使用std::hash::hash;
使用std::hash::Hasher;
使用std::collections::hash_map::DefaultHasher;
pub fn main(){
{
#[导出(散列)]
枚举E1{
第一(i32),
第二(弦),
}
#[导出(散列)]
枚举E2是。这是有保证的,因为String
实现了借用
实施is的部分合同是:
此外,在提供附加特性的实现时,需要考虑它们作为该基础类型的表示的结果是否应该与基础类型的行为相同。当依赖于这些附加特性的相同行为时,泛型代码通常使用借用
这些特征可能会作为额外的特征边界出现
特别是Eq
,Ord
和Hash
对于借用值和拥有值必须等效:x.borrow()==y.borrow()
应给出与x==y
相同的结果
在标准库中,使用了借用
特性。借用
可以在哈希映射
上将&str
传递给获取
。自然地,为了实现这一点,&String
和&str
必须为同一字符串生成相同的哈希,因此对Borro的要求w
。该要求在HashMap::get
的文档中重复:
键可以是映射键类型的任何借用形式,但借用形式上的Hash
和Eq
必须与键类型匹配
Traits无法在代码中定义这样的需求,因此可能存在不一致的实现,因为编译器无法强制执行这些需求。然而,这样的实现会破坏HashMap
idk关于保证的规定,但是。如果这一点发生变化,我会感到惊讶。