I'm happy to announce that Rust's new hashing framework has landed in:

https://github.com/mozilla/rust/pull/11863
https://github.com/mozilla/rust/pull/12492

This PR has has changed how to declare a type is hashable. Here's a full
example on how to hash a value using either the new `#[deriving(Hash)]` or
manual implementation.

```
use std::hash::{Hash, hash};
use std::hash::sip::SipState;

#[deriving(Hash)]
struct Foo {
    a: ~str,
    b: uint,
    c: bool,
}

struct Bar {
    a: ~str,
    b: uint,
    c: bool,
}

impl Hash for Bar {
    fn hash(&self, state: &mut SipState) {
        self.a.hash(state);
        self.b.hash(state);
        self.c.hash(state);
    }
}

fn main() {
    let foo = Foo { a: ~"hello world", b: 5, c: true };
    println!("{}", hash(&foo));

    let bar = Bar { a: ~"hello world", b: 5, c: true };
    println!("{}", hash(&bar));
}
```

We also have experimental support for hashers that compute a value off a
stream of bytes:

```
use std::hash::{Hash, Hasher};
use std::io::IoResult;

#[deriving(Hash)] // automatically provides hashing from a stream of bytes
struct Foo {
    a: ~str,
    b: uint,
    c: bool,
}

struct Bar {
    a: ~str,
    b: uint,
    c: bool,
}

#[allow(default_type_param_usage)]
impl<S: Writer> Hash<S> for Bar {
    fn hash(&self, state: &mut S) {
        self.a.hash(state);
        self.b.hash(state);
        self.c.hash(state);
    }
}

struct SumState {
    sum: u64,
}

impl Writer for SumState {
    fn write(&mut self, bytes: &[u8]) -> IoResult<()> {
        for byte in bytes.iter() {
            self.sum += *byte as u64;
        }
        Ok(())
    }
}

struct SumHasher;

#[allow(default_type_param_usage)]
impl Hasher<SumState> for SumHasher {
    fn hash<T: Hash<SumState>>(&self, value: &T) -> u64 {
        let mut state = SumState { sum: 0 };
        value.hash(&mut state);
        state.sum
    }
}

fn main() {
    let hasher = SumHasher;
    let foo = Foo { a: ~"hello world", b: 5, c: true };
    println!("{}", hasher.hash(&foo));
    let bar = Bar { a: ~"hello world", b: 5, c: true };
    println!("{}", hasher.hash(&bar));
}
```

Finally, we also support completely custom hash computation:

```
use std::hash::{Hash, Hasher};

struct Foo {
    hash: u64
}

#[allow(default_type_param_usage)]
impl Hash<u64> for Foo {
    fn hash(&self, state: &mut u64) {
        *state = self.hash
    }
}

struct CustomHasher;

#[allow(default_type_param_usage)]
impl Hasher<u64> for CustomHasher {
    fn hash<T: Hash<u64>>(&self, value: &T) -> u64 {
        let mut state = 0;
        value.hash(&mut state);
        state
    }
}

fn main() {
    let hasher = CustomHasher;
    let foo = Foo { hash: 5 };
    println!("{}", hasher.hash(&foo));
}
```

This may break over the next couple days/weeks as we figure out the right
way to do this. Furthermore, HashMaps have not yet been updated to take
advantage of the custom hashers, but that should be coming later on this
week.

I hope they work well for all of you. If you run into any trouble, please
file bugs and cc @erickt on the ticket.

Thanks,
Erick
_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to