gpt4 book ai didi

hash - 自有字符串和借用字符串是否保证散列到相同的值?

转载 作者:行者123 更新时间:2023-12-03 11:25:22 24 4
gpt4 key购买 nike

Stringstr都实现 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);
}

我正在编写利用 raw_entry 中的这种行为的代码。 HashMap的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);
}
}

是否记录了有关此类保证的任何地方?我认为必须提供此类保证(否则我认为无法正确实现 contains_key()HashMap 方法,因为参数可以是 key 的任何借用形式),但我找不到此保证记录任何地方。

最佳答案

是的。这是有保证的,因为 String工具Borrow<str> .

实现 Borrow 的契约(Contract)的一部分是:

Further, when providing implementations for additional traits, it needs to be considered whether they should behave identical to those of the underlying type as a consequence of acting as a representation of that underlying type. Generic code typically uses Borrow<T> when it relies on the identical behavior of these additional trait implementations. These traits will likely appear as additional trait bounds.

In particular Eq, Ord and Hash must be equivalent for borrowed and owned values: x.borrow() == y.borrow() should give the same result as x == y.



在标准库中, Borrow特性用于 HashMap::get . Borrow可以通过 &strgetHashMap<String, _> .当然,为了让这个工作, &String&str必须为相同的字符串产生相同的散列,因此对 Borrow 的要求.在 HashMap::get 的文档中重复了该要求。 :

The key may be any borrowed form of the map's key type, but Hash and Eq on the borrowed form must match those for the key type.



Traits 无法在代码中定义这样的要求,因此可能存在不符合要求的实现,因为编译器无法强制执行这些要求。然而,这样的实现会破坏 HashMap .

关于hash - 自有字符串和借用字符串是否保证散列到相同的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61692668/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com