Hash 与 Hasher

如果一个类型实现了 Hash trait, 就表示该类型的值可用在需要计算哈稀的地方.

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 { ... }
}

通常可以直接 [derive(Hash)] 让编译器自动实现:

#![allow(unused)]
fn main() {
#[derive(Hash)]
pub struct Point2D {
    x: i32,
    y: i32,
}
}

以上代码就相当于手动实现的:

#![allow(unused)]
fn main() {
use std::hash::{Hash, Hasher};

pub struct Point2D {
    x: i32,
    y: i32,
}

impl Hash for Point2D {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.x.hash(state);
        self.y.hash(state);
    }
}
}

比如标准库里的 HashMapHashSet 都依赖于这个 trait.

Hash 与 Eq

如果同一个类型的两个值相等, 那它们的哈稀也该应该相等. 所以平时都是一并实现这两个 trait:

#![allow(unused)]
fn main() {
#[derive(PartialEq, Eq, Hash)]
pub struct Point2D {
  x: i32,
  y: i32,
}
}

标准库里的 hash 函数实现

目前, Rust 标准库使用 SipHash 1-3 作为默认的哈稀函数, 具体可以参考以下链接: