Trait std::hash::Hash 1.0.0[−][src]
pub trait Hash {
fn hash<H>(&self, state: &mut H)
where
H: Hasher;
fn hash_slice<H>(data: &[Self], state: &mut H)
where
H: Hasher,
{ ... }
}
Expand description
可散列的类型。
实现 Hash
的类型可以通过 Hasher
的实例进行 hash
化。
实现 Hash
如果所有字段都要实现 Hash
,则可以用 #[derive(Hash)]
派生 Hash
。
产生的哈希将是在每个字段上调用 hash
的值的组合。
#[derive(Hash)]
struct Rustacean {
name: String,
country: String,
}
Run如果您需要更多地控制值的散列方式,则当然可以自己实现 Hash
trait:
use std::hash::{Hash, Hasher};
struct Person {
id: u32,
name: String,
phone: u64,
}
impl Hash for Person {
fn hash<H: Hasher>(&self, state: &mut H) {
self.id.hash(state);
self.phone.hash(state);
}
}
RunHash
和 Eq
同时实现 Hash
和 Eq
时,保持以下属性很重要:
k1 == k2 -> hash(k1) == hash(k2)
换句话说,如果两个键相等,则它们的哈希也必须相等。
HashMap
和 HashSet
都依赖于这种行为。
值得庆幸的是,在使用 #[derive(PartialEq, Eq, Hash)]
派生 Eq
和 Hash
时,您不必担心维护此属性。
前缀冲突
hash
的实现应该确保它们传递给 Hasher
的数据是无前缀的。
也就是说,不相等的值应该导致写入两个不同的值序列,并且两个序列中的任何一个都不应该是另一个的前缀。
例如,Hash
for &str
的标准实现将额外的 0xFF
字节传递给 Hasher
,以便值 ("ab", "c")
和 ("a", "bc")
哈希不同。
Portability
由于字节序和类型大小的差异,由 Hash
提供给 Hasher
的数据不应被视为跨平台可移植的。
此外,大多数标准库类型传递的数据在不同的编译器版本之间不应该被认为是稳定的。
这意味着测试不应探测硬编码的哈希值或提供给 Hasher
的数据,而应检查与 Eq
的一致性。
旨在在平台或编译器版本之间可移植的序列化格式应避免编码哈希或仅依赖提供额外保证的 Hash
和 Hasher
实现。
Required methods
Provided methods
1.3.0[src]fn hash_slice<H>(data: &[Self], state: &mut H) where
H: Hasher,
fn hash_slice<H>(data: &[Self], state: &mut H) where
H: Hasher,
将这种类型的切片送入给定的 Hasher
中。
此方法是为了方便起见,但它的实现也明确未指定。
它不能保证等同于 hash
的重复调用,并且 Hash
的实现应该记住这一点,如果在 PartialEq
实现中没有将 6 视为整个单元,则调用 hash
本身。
例如,一个 VecDeque
实现可能天真地调用 as_slices
然后 hash_slice
对每个调用 hash_slice
,但这是错误的,因为两个切片可以随调用更改为 make_contiguous
而不会影响 PartialEq
结果。
由于这些切片不被视为单一单元,而是更大双端队列的一部分,因此无法使用此方法。
Examples
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
let mut hasher = DefaultHasher::new();
let numbers = [6, 28, 496, 8128];
Hash::hash_slice(&numbers, &mut hasher);
println!("Hash is {:x}!", hasher.finish());
RunImplementors
impl<A, B, C, D, E> Hash for (A, B, C, D, E) where
A: Hash,
B: Hash,
C: Hash,
D: Hash,
E: Hash + ?Sized,
impl<A, B, C, D, E, F> Hash for (A, B, C, D, E, F) where
A: Hash,
B: Hash,
C: Hash,
D: Hash,
E: Hash,
F: Hash + ?Sized,
impl<A, B, C, D, E, F, G> Hash for (A, B, C, D, E, F, G) where
A: Hash,
B: Hash,
C: Hash,
D: Hash,
E: Hash,
F: Hash,
G: Hash + ?Sized,
impl<A, B, C, D, E, F, G, H> Hash for (A, B, C, D, E, F, G, H) where
A: Hash,
B: Hash,
C: Hash,
D: Hash,
E: Hash,
F: Hash,
G: Hash,
H: Hash + ?Sized,
impl<A, B, C, D, E, F, G, H, I> Hash for (A, B, C, D, E, F, G, H, I) where
A: Hash,
B: Hash,
C: Hash,
D: Hash,
E: Hash,
F: Hash,
G: Hash,
H: Hash,
I: Hash + ?Sized,
impl<A, B, C, D, E, F, G, H, I, J> Hash for (A, B, C, D, E, F, G, H, I, J) where
A: Hash,
B: Hash,
C: Hash,
D: Hash,
E: Hash,
F: Hash,
G: Hash,
H: Hash,
I: Hash,
J: Hash + ?Sized,
impl<A, B, C, D, E, F, G, H, I, J, K> Hash for (A, B, C, D, E, F, G, H, I, J, K) where
A: Hash,
B: Hash,
C: Hash,
D: Hash,
E: Hash,
F: Hash,
G: Hash,
H: Hash,
I: Hash,
J: Hash,
K: Hash + ?Sized,
impl<A, B, C, D, E, F, G, H, I, J, K, L> Hash for (A, B, C, D, E, F, G, H, I, J, K, L) where
A: Hash,
B: Hash,
C: Hash,
D: Hash,
E: Hash,
F: Hash,
G: Hash,
H: Hash,
I: Hash,
J: Hash,
K: Hash,
L: Hash + ?Sized,
impl<Ret, A, B, C, D, E, F, G> Hash for unsafe extern "C" fn(A, B, C, D, E, F, G, ...) -> Ret
impl<Ret, A, B, C, D, E, F, G, H> Hash for extern "C" fn(A, B, C, D, E, F, G, H, ...) -> Ret
impl<Ret, A, B, C, D, E, F, G, H> Hash for unsafe extern "C" fn(A, B, C, D, E, F, G, H) -> Ret
impl<Ret, A, B, C, D, E, F, G, H> Hash for unsafe extern "C" fn(A, B, C, D, E, F, G, H, ...) -> Ret
impl<Ret, A, B, C, D, E, F, G, H, I> Hash for extern "C" fn(A, B, C, D, E, F, G, H, I) -> Ret
impl<Ret, A, B, C, D, E, F, G, H, I> Hash for extern "C" fn(A, B, C, D, E, F, G, H, I, ...) -> Ret
impl<Ret, A, B, C, D, E, F, G, H, I> Hash for unsafe extern "C" fn(A, B, C, D, E, F, G, H, I) -> Ret
impl<Ret, A, B, C, D, E, F, G, H, I> Hash for unsafe extern "C" fn(A, B, C, D, E, F, G, H, I, ...) -> Ret
impl<Ret, A, B, C, D, E, F, G, H, I, J> Hash for extern "C" fn(A, B, C, D, E, F, G, H, I, J) -> Ret
impl<Ret, A, B, C, D, E, F, G, H, I, J> Hash for extern "C" fn(A, B, C, D, E, F, G, H, I, J, ...) -> Ret
impl<Ret, A, B, C, D, E, F, G, H, I, J> Hash for unsafe fn(A, B, C, D, E, F, G, H, I, J) -> Ret
impl<Ret, A, B, C, D, E, F, G, H, I, J> Hash for unsafe extern "C" fn(A, B, C, D, E, F, G, H, I, J) -> Ret
impl<Ret, A, B, C, D, E, F, G, H, I, J> Hash for unsafe extern "C" fn(A, B, C, D, E, F, G, H, I, J, ...) -> Ret
impl<Ret, A, B, C, D, E, F, G, H, I, J, K> Hash for fn(A, B, C, D, E, F, G, H, I, J, K) -> Ret
impl<Ret, A, B, C, D, E, F, G, H, I, J, K> Hash for extern "C" fn(A, B, C, D, E, F, G, H, I, J, K) -> Ret
impl<Ret, A, B, C, D, E, F, G, H, I, J, K> Hash for extern "C" fn(A, B, C, D, E, F, G, H, I, J, K, ...) -> Ret
impl<Ret, A, B, C, D, E, F, G, H, I, J, K> Hash for unsafe fn(A, B, C, D, E, F, G, H, I, J, K) -> Ret
impl<Ret, A, B, C, D, E, F, G, H, I, J, K> Hash for unsafe extern "C" fn(A, B, C, D, E, F, G, H, I, J, K) -> Ret
impl<Ret, A, B, C, D, E, F, G, H, I, J, K> Hash for unsafe extern "C" fn(A, B, C, D, E, F, G, H, I, J, K, ...) -> Ret
impl<Ret, A, B, C, D, E, F, G, H, I, J, K, L> Hash for fn(A, B, C, D, E, F, G, H, I, J, K, L) -> Ret
impl<Ret, A, B, C, D, E, F, G, H, I, J, K, L> Hash for extern "C" fn(A, B, C, D, E, F, G, H, I, J, K, L) -> Ret
impl<Ret, A, B, C, D, E, F, G, H, I, J, K, L> Hash for extern "C" fn(A, B, C, D, E, F, G, H, I, J, K, L, ...) -> Ret
impl<Ret, A, B, C, D, E, F, G, H, I, J, K, L> Hash for unsafe fn(A, B, C, D, E, F, G, H, I, J, K, L) -> Ret
impl<Ret, A, B, C, D, E, F, G, H, I, J, K, L> Hash for unsafe extern "C" fn(A, B, C, D, E, F, G, H, I, J, K, L) -> Ret
impl<Ret, A, B, C, D, E, F, G, H, I, J, K, L> Hash for unsafe extern "C" fn(A, B, C, D, E, F, G, H, I, J, K, L, ...) -> Ret
根据 core::borrow::Borrow
实现的要求,vector 的哈希值与相应的 3 的哈希值相同。
#![feature(build_hasher_simple_hash_one)]
use std::hash::BuildHasher;
let b = std::collections::hash_map::RandomState::new();
let v: Vec<u8> = vec![0xa8, 0x3c, 0x09];
let s: &[u8] = &[0xa8, 0x3c, 0x09];
assert_eq!(b.hash_one(v), b.hash_one(s));
Runimpl<T, const LANES: usize> Hash for Simd<T, LANES> where
T: SimdElement + Hash,
LaneCount<LANES>: SupportedLaneCount,
数组的哈希值与对应的 X 像素的哈希值相同,符合实现的要求。
#![feature(build_hasher_simple_hash_one)]
use std::hash::BuildHasher;
let b = std::collections::hash_map::RandomState::new();
let a: [u8; 3] = [0xa8, 0x3c, 0x09];
let s: &[u8] = &[0xa8, 0x3c, 0x09];
assert_eq!(b.hash_one(a), b.hash_one(s));
Run