Trait core::hash::Hash

1.0.0 · source ·
pub trait Hash {
    // Required method
    fn hash<H: Hasher>(&self, state: &mut H);

    // Provided method
    fn hash_slice<H: Hasher>(data: &[Self], state: &mut H)
       where 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);
    }
}
Run

HashEq

同时实现 HashEq 时,保持以下属性很重要:

k1 == k2 -> hash(k1) == hash(k2)

换句话说,如果两个键相等,则它们的哈希也必须相等。 HashMapHashSet 都依赖于这种行为。

值得庆幸的是,在使用 #[derive(PartialEq, Eq, Hash)] 派生 EqHash 时,您不必担心维护此属性。

前缀冲突

hash 的实现应该确保它们传递给 Hasher 的数据是无前缀的。 也就是说,不相等的值应该导致写入两个不同的值序列,并且这两个序列中的任何一个都不应该是另一个序列的前缀。

例如,Hash for &str 的标准实现将额外的 0xFF 字节传递给 Hasher,以便值 ("ab", "c")("a", "bc") 哈希不同。

Portability

由于字节序和类型大小的差异,由 Hash 提供给 Hasher 的数据不应被视为跨平台可移植的。 此外,大多数标准库类型传递的数据在不同的编译器版本之间不应该被认为是稳定的。

这意味着测试不应探测硬编码的哈希值或提供给 Hasher 的数据,而应检查与 Eq 的一致性。

旨在在平台或编译器版本之间可移植的序列化格式应避免编码哈希或仅依赖提供额外保证的 HashHasher 实现。

Required Methods§

source

fn hash<H: Hasher>(&self, state: &mut H)

将该值输入给定的 Hasher

Examples
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};

let mut hasher = DefaultHasher::new();
7920.hash(&mut hasher);
println!("Hash is {:x}!", hasher.finish());
Run

Provided Methods§

1.3.0 · source

fn hash_slice<H: Hasher>(data: &[Self], state: &mut H)where 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());
Run

Implementors§

source§

impl Hash for AsciiChar

source§

impl Hash for core::cmp::Ordering

1.44.0 · source§

impl Hash for Infallible

1.7.0 · source§

impl Hash for IpAddr

source§

impl Hash for Ipv6MulticastScope

source§

impl Hash for SocketAddr

source§

impl Hash for Which

source§

impl Hash for core::sync::atomic::Ordering

source§

impl Hash for bool

source§

impl Hash for char

source§

impl Hash for i8

source§

impl Hash for i16

source§

impl Hash for i32

source§

impl Hash for i64

source§

impl Hash for i128

source§

impl Hash for isize

1.29.0 · source§

impl Hash for !

source§

impl Hash for str

source§

impl Hash for u8

source§

impl Hash for u16

source§

impl Hash for u32

source§

impl Hash for u64

source§

impl Hash for u128

source§

impl Hash for ()

source§

impl Hash for usize

1.28.0 · source§

impl Hash for Layout

source§

impl Hash for TypeId

1.64.0 · source§

impl Hash for CStr

source§

impl Hash for Error

1.33.0 · source§

impl Hash for PhantomPinned

source§

impl Hash for Ipv4Addr

source§

impl Hash for Ipv6Addr

source§

impl Hash for SocketAddrV4

source§

impl Hash for SocketAddrV6

1.34.0 · source§

impl Hash for NonZeroI8

1.34.0 · source§

impl Hash for NonZeroI16

1.34.0 · source§

impl Hash for NonZeroI32

1.34.0 · source§

impl Hash for NonZeroI64

1.34.0 · source§

impl Hash for NonZeroI128

1.34.0 · source§

impl Hash for NonZeroIsize

1.28.0 · source§

impl Hash for NonZeroU8

1.28.0 · source§

impl Hash for NonZeroU16

1.28.0 · source§

impl Hash for NonZeroU32

1.28.0 · source§

impl Hash for NonZeroU64

1.28.0 · source§

impl Hash for NonZeroU128

1.28.0 · source§

impl Hash for NonZeroUsize

source§

impl Hash for RangeFull

source§

impl Hash for Alignment

1.3.0 · source§

impl Hash for Duration

1.10.0 · source§

impl<'a> Hash for Location<'a>

1.55.0 · source§

impl<B: Hash, C: Hash> Hash for ControlFlow<B, C>

source§

impl<Dyn: ?Sized> Hash for DynMetadata<Dyn>

1.4.0 · source§

impl<F: FnPtr> Hash for F

source§

impl<Idx: Hash> Hash for Range<Idx>

source§

impl<Idx: Hash> Hash for RangeFrom<Idx>

1.26.0 · source§

impl<Idx: Hash> Hash for RangeInclusive<Idx>

source§

impl<Idx: Hash> Hash for RangeTo<Idx>

1.26.0 · source§

impl<Idx: Hash> Hash for RangeToInclusive<Idx>

1.41.0 · source§

impl<P: Deref<Target: Hash>> Hash for Pin<P>

source§

impl<T> Hash for (T₁, T₂, …, Tₙ)where T: ?Sized + Hash,

This trait is implemented for tuples up to twelve items long.

1.21.0 · source§

impl<T> Hash for Discriminant<T>

source§

impl<T, const N: usize> Hash for Simd<T, N>where LaneCount<N>: SupportedLaneCount, T: SimdElement + Hash,

1.20.0 · source§

impl<T: Hash + ?Sized> Hash for ManuallyDrop<T>

1.17.0 · source§

impl<T: Hash> Hash for Bound<T>

source§

impl<T: Hash> Hash for Option<T>

1.36.0 · source§

impl<T: Hash> Hash for Poll<T>

source§

impl<T: Hash> Hash for [T]

1.19.0 · source§

impl<T: Hash> Hash for Reverse<T>

source§

impl<T: Hash> Hash for Saturating<T>

source§

impl<T: Hash> Hash for Wrapping<T>

source§

impl<T: Hash, E: Hash> Hash for Result<T, E>

source§

impl<T: Hash, const N: usize> Hash for [T; N]

数组的哈希值与对应的 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
source§

impl<T: ?Sized + Hash> Hash for &T

source§

impl<T: ?Sized + Hash> Hash for &mut T

source§

impl<T: ?Sized> Hash for *const T

source§

impl<T: ?Sized> Hash for *mut T

source§

impl<T: ?Sized> Hash for PhantomData<T>

1.25.0 · source§

impl<T: ?Sized> Hash for NonNull<T>

source§

impl<Y: Hash, R: Hash> Hash for GeneratorState<Y, R>