Reputation: 137
I'm trying to declare a struct which contains a HashMap, but it won't let me derive Hash.
use std::collections::HashMap;
#[derive(PartialEq,Eq,Hash)]
struct Environment{
names:HashMap<String,String>,
}
Upvotes: 3
Views: 1397
Reputation: 169328
HashMap
itself does not implement Hash
, so an automatic derivation is impossible. You would need to implement Hash
manually. Note that you have to be careful to ensure that a manual implementation is compatible with the PartialEq
implementation of HashMap
; for example, you would need to ensure that you hash key-value pairs in a consistent order, because key order is irrelevant to the PartialEq
implementation.
One possible implementation collects all (key, value)
pairs into a vector, sorts it on key
, and hashes the resulting vector:
impl Hash for Environment {
fn hash<H: Hasher>(&self, h: &mut H) {
let mut pairs: Vec<_> = self.names.iter().collect();
pairs.sort_by_key(|i| i.0);
Hash::hash(&pairs, h);
}
}
Note that this requires allocating a vector of self.len()
elements, but does not require duplicating the strings (they are borrowed).
Consider instead using BTreeMap<String, String>
. This type implements Hash
, so automatic derivation of Hash
is possible:
#[derive(PartialEq, Eq, Hash)]
struct Environment{
names: BTreeMap<String, String>,
}
Upvotes: 5