Trait std::hash::Hash1.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);
    }
}
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") 哈希不同。

Required methods

将该值输入给定的 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

将这种类型的切片送入给定的 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

根据 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));
Run

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