pub trait Hash {
// Required method
fn hash<H>(&self, state: &mut H)
where H: Hasher;
// Provided method
fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher,
Self: Sized { ... }
}
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 · sourcefn hash_slice<H>(data: &[Self], state: &mut H)where
H: Hasher,
Self: Sized,
fn hash_slice<H>(data: &[Self], state: &mut H)where H: Hasher, Self: Sized,
将这种类型的切片送入给定的 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 Hash for AsciiChar
impl Hash for std::cmp::Ordering
impl Hash for Infallible
impl Hash for ErrorKind
impl Hash for IpAddr
impl Hash for Ipv6MulticastScope
impl Hash for SocketAddr
impl Hash for Which
impl Hash for std::sync::atomic::Ordering
impl Hash for bool
impl Hash for char
impl Hash for i8
impl Hash for i16
impl Hash for i32
impl Hash for i64
impl Hash for i128
impl Hash for isize
impl Hash for !
impl Hash for str
impl Hash for u8
impl Hash for u16
impl Hash for u32
impl Hash for u64
impl Hash for u128
impl Hash for ()
impl Hash for usize
impl Hash for Layout
impl Hash for TypeId
impl Hash for CStr
impl Hash for CString
impl Hash for OsStr
impl Hash for OsString
impl Hash for Error
impl Hash for FileType
impl Hash for PhantomPinned
impl Hash for Ipv4Addr
impl Hash for Ipv6Addr
impl Hash for SocketAddrV4
impl Hash for SocketAddrV6
impl Hash for NonZeroI8
impl Hash for NonZeroI16
impl Hash for NonZeroI32
impl Hash for NonZeroI64
impl Hash for NonZeroI128
impl Hash for NonZeroIsize
impl Hash for NonZeroU8
impl Hash for NonZeroU16
impl Hash for NonZeroU32
impl Hash for NonZeroU64
impl Hash for NonZeroU128
impl Hash for NonZeroUsize
impl Hash for RangeFull
impl Hash for UCred
impl Hash for Path
impl Hash for PathBuf
impl Hash for PrefixComponent<'_>
impl Hash for Alignment
impl Hash for String
impl Hash for ThreadId
impl Hash for Duration
impl Hash for Instant
impl Hash for SystemTime
impl<'a> Hash for Component<'a>
impl<'a> Hash for Prefix<'a>
impl<'a> Hash for Location<'a>
impl<B> Hash for Cow<'_, B>where B: Hash + ToOwned + ?Sized,
impl<B, C> Hash for ControlFlow<B, C>where B: Hash, C: Hash,
impl<Dyn> Hash for DynMetadata<Dyn>where Dyn: ?Sized,
impl<F> Hash for Fwhere F: FnPtr,
impl<Idx> Hash for Range<Idx>where Idx: Hash,
impl<Idx> Hash for RangeFrom<Idx>where Idx: Hash,
impl<Idx> Hash for RangeInclusive<Idx>where Idx: Hash,
impl<Idx> Hash for RangeTo<Idx>where Idx: Hash,
impl<Idx> Hash for RangeToInclusive<Idx>where Idx: Hash,
impl<K, V, A> Hash for BTreeMap<K, V, A>where K: Hash, V: Hash, A: Allocator + Clone,
impl<P> Hash for Pin<P>where P: Deref, <P as Deref>::Target: Hash,
impl<T> Hash for Bound<T>where T: Hash,
impl<T> Hash for Option<T>where T: Hash,
impl<T> Hash for Poll<T>where T: Hash,
impl<T> Hash for *const Twhere T: ?Sized,
impl<T> Hash for *mut Twhere T: ?Sized,
impl<T> Hash for &Twhere T: Hash + ?Sized,
impl<T> Hash for &mut Twhere T: Hash + ?Sized,
impl<T> Hash for [T]where T: Hash,
impl<T> Hash for (T₁, T₂, …, Tₙ)where T: Hash + ?Sized,
This trait is implemented for tuples up to twelve items long.
impl<T> Hash for Reverse<T>where T: Hash,
impl<T> Hash for PhantomData<T>where T: ?Sized,
impl<T> Hash for Discriminant<T>
impl<T> Hash for ManuallyDrop<T>where T: Hash + ?Sized,
impl<T> Hash for Saturating<T>where T: Hash,
impl<T> Hash for Wrapping<T>where T: Hash,
impl<T> Hash for NonNull<T>where T: ?Sized,
impl<T> Hash for Rc<T>where T: Hash + ?Sized,
impl<T> Hash for Arc<T>where T: Hash + ?Sized,
impl<T, A> Hash for Box<T, A>where T: Hash + ?Sized, A: Allocator,
impl<T, A> Hash for BTreeSet<T, A>where T: Hash, A: Allocator + Clone,
impl<T, A> Hash for LinkedList<T, A>where T: Hash, A: Allocator,
impl<T, A> Hash for VecDeque<T, A>where T: Hash, A: Allocator,
impl<T, A> Hash for Vec<T, A>where T: Hash, A: Allocator,
根据 core::borrow::Borrow
实现的要求,vector 的哈希值与相应的 3 的哈希值相同。
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, E> Hash for Result<T, E>where T: Hash, E: Hash,
impl<T, const N: usize> Hash for [T; N]where T: Hash,
数组的哈希值与对应的 X 像素的哈希值相同,符合实现的要求。
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