Ben Chuanlong Du's Blog

It is never too late to learn.

Hash in Rust

Things on this page are fragmentary and immature notes/thoughts of the author. Please read with your own judgement!

In [ ]:
:timing
:sccache 1
  1. Hashing calculation in Rust is different from Java, Python, etc. The hash function of the Hash trait does not return a hash value, but instead feed hash into a Hasher. The Hasher is responsible for generating the final hash code based on hash values of different components. This is one step further simplification over Java and Python's way of calculating hash values (in which users are responsible for deciding how to combine different hash values.)

  2. You should either implement both Hash and Eq traits of neither of them. When implementing Hash and Eq traits, make sure they satisfy the constrait k1 == k2 -> hash(k1) == hash(k2).

PartialEq, Eq and Hash

#[derive(PartialEq, Eq, Hash)] Whenever you implement Eq or Hash, you should implement all three of PartialEq, Eq and Hash. One simple way to do this is to use #[derive(PartialEq, Eq, Hash)]. When you implement PartialEq, Eq and Hash traits, make sure that k1 == k2 -> hash(k1) == hash(k2). When deriving PartialEq, Eq and Hash, the constraint is hold automatically so that you don't have to worry about it.

In [2]:
struct Person {
    name: String,
    age: i32,
}
In [7]:
let p3 = Person::new("Ben Du", 30);
In [2]:
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());
Hash is fa637a3502273993!

Calculate Hash of An Object

In [5]:
use std::hash::{Hash, Hasher};
In [6]:
impl Hash for Person {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.name.hash(state);
        self.age.hash(state);
    }
}
In [ ]:

Comments