如何在 HashSet 或 HashMap 中使用自定义哈希函数?
How can I use a custom hash function in a HashSet or HashMap?
由于 SipHasher 对于我的用例来说太慢了,我正在尝试实现自定义哈希函数。我找到了 an example,我将其用作编译所有内容的基础。
我当前的代码如下所示:
use std::collections::hash_state::{DefaultState};
use std::collections::{HashMap, HashSet};
use std::default::Default;
use std::hash::{Hash, Hasher, SipHasher};
use std::marker;
pub struct FnvHasher(u64);
impl Default for FnvHasher {
fn default() -> FnvHasher { FnvHasher(0xcbf29ce484222325) }
}
impl Hasher for FnvHasher {
fn write(&mut self, bytes: &[u8]) {
let FnvHasher(mut hash) = *self;
for byte in bytes {
hash = hash ^ (*byte as u64);
hash = hash * 0x100000001b3;
}
*self = FnvHasher(hash);
}
fn finish(&self) -> u64 { self.0 }
}
fn main() {
let mut set:HashSet<i64, DefaultState<FnvHasher>> = HashSet::with_hash_state(DefaultState::<FnvHasher>);
}
编译时出现以下错误消息:
$ rustc -V
rustc 1.0.0-nightly (522d09dfe 2015-02-19) (built 2015-02-19)
$ rustc hash.rs
hash.rs:26:86: 26:111 error: mismatched types:
expected `std::collections::hash::state::DefaultState<FnvHasher>`,
found `fn(core::marker::PhantomData<FnvHasher>) -> std::collections::hash::state::DefaultState<FnvHasher> {std::collections::hash::state::DefaultState}`
(expected struct `std::collections::hash::state::DefaultState`,
found fn item) [E0308]
hash.rs:26 let mut set:HashSet<i64, DefaultState<FnvHasher>> = HashSet::with_hash_state(DefaultState::<FnvHasher>);
^~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
如何让上面的例子在 HashSet/HashMap 中编译或使用自定义哈希函数?
看看DefaultState
的定义:
pub struct DefaultState<H>(marker::PhantomData<H>);
你对待它就像对待它以前一样:
pub struct DefaultState<H>;
此更改是最近的;现在必须明确使用通用参数。
为此您现在必须使用 Default::default()
,因为该字段是私有的,防止写入文字表达式。因此,DefaultState::<FnvHasher>
变为 Default::default()
.
一旦你为此使用 Default::default()
,你不妨全力以赴,将 HashSet::with_hash_state(Default::default())
替换为 Default::default()
:
let mut set: HashSet<i64, DefaultState<FnvHasher>> = Default::default();
Rust 1.7 stabilized the use of custom hashers. For example, you can use FnvHasher
from the fnv 板条箱
extern crate fnv;
use std::collections::HashMap;
use std::hash::BuildHasherDefault;
use fnv::FnvHasher;
type HashMapFnv<K, V> = HashMap<K, V, BuildHasherDefault<FnvHasher>>;
fn main() {
let mut map = HashMapFnv::default();
map.insert(1, "Hello");
map.insert(2, ", world!");
println!("{:?}", map);
}
由于 SipHasher 对于我的用例来说太慢了,我正在尝试实现自定义哈希函数。我找到了 an example,我将其用作编译所有内容的基础。
我当前的代码如下所示:
use std::collections::hash_state::{DefaultState};
use std::collections::{HashMap, HashSet};
use std::default::Default;
use std::hash::{Hash, Hasher, SipHasher};
use std::marker;
pub struct FnvHasher(u64);
impl Default for FnvHasher {
fn default() -> FnvHasher { FnvHasher(0xcbf29ce484222325) }
}
impl Hasher for FnvHasher {
fn write(&mut self, bytes: &[u8]) {
let FnvHasher(mut hash) = *self;
for byte in bytes {
hash = hash ^ (*byte as u64);
hash = hash * 0x100000001b3;
}
*self = FnvHasher(hash);
}
fn finish(&self) -> u64 { self.0 }
}
fn main() {
let mut set:HashSet<i64, DefaultState<FnvHasher>> = HashSet::with_hash_state(DefaultState::<FnvHasher>);
}
编译时出现以下错误消息:
$ rustc -V
rustc 1.0.0-nightly (522d09dfe 2015-02-19) (built 2015-02-19)
$ rustc hash.rs
hash.rs:26:86: 26:111 error: mismatched types:
expected `std::collections::hash::state::DefaultState<FnvHasher>`,
found `fn(core::marker::PhantomData<FnvHasher>) -> std::collections::hash::state::DefaultState<FnvHasher> {std::collections::hash::state::DefaultState}`
(expected struct `std::collections::hash::state::DefaultState`,
found fn item) [E0308]
hash.rs:26 let mut set:HashSet<i64, DefaultState<FnvHasher>> = HashSet::with_hash_state(DefaultState::<FnvHasher>);
^~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
如何让上面的例子在 HashSet/HashMap 中编译或使用自定义哈希函数?
看看DefaultState
的定义:
pub struct DefaultState<H>(marker::PhantomData<H>);
你对待它就像对待它以前一样:
pub struct DefaultState<H>;
此更改是最近的;现在必须明确使用通用参数。
为此您现在必须使用 Default::default()
,因为该字段是私有的,防止写入文字表达式。因此,DefaultState::<FnvHasher>
变为 Default::default()
.
一旦你为此使用 Default::default()
,你不妨全力以赴,将 HashSet::with_hash_state(Default::default())
替换为 Default::default()
:
let mut set: HashSet<i64, DefaultState<FnvHasher>> = Default::default();
Rust 1.7 stabilized the use of custom hashers. For example, you can use FnvHasher
from the fnv 板条箱
extern crate fnv;
use std::collections::HashMap;
use std::hash::BuildHasherDefault;
use fnv::FnvHasher;
type HashMapFnv<K, V> = HashMap<K, V, BuildHasherDefault<FnvHasher>>;
fn main() {
let mut map = HashMapFnv::default();
map.insert(1, "Hello");
map.insert(2, ", world!");
println!("{:?}", map);
}