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关于保证的规定,但是。如果这一点发生变化,我会感到惊讶。