I want to build a hashmap where they keys are references. I want that equality for those references means reference equality, i.e. both references borrow the same object.
use std::collections::hash_map::HashMap;
struct SomeKey();
struct SomeValue();
fn main() {
let m = HashMap::<&SomeKey, SomeValue>::new();
let t = SomeKey();
m.get(&t);
}
Unfortunately, this fails and the compiler tells me that &SomeKey
doesn't implement Hash
/Eq
.
error[E0599]: the method `get` exists for struct `HashMap<&SomeKey, SomeValue>`, but its trait bounds were not satisfied
--> src/main.rs:10:7
|
10 | m.get(&t);
| ^^^ method cannot be called on `HashMap<&SomeKey, SomeValue>` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`&SomeKey: Eq`
`&SomeKey: Hash`
I noticed that if i implement Eq+Hash
for SomeKey
, then it works, but that'll likely use the underlying object equality then which is not what I want.
Is there a way I can use references as hash map keys based on pointer equality?
You could use the by_address
crate. It wraps any pointer/reference type to compare objects by address instead of by contents.
use std::collections::hash_map::HashMap;
use by_address::ByAddress;
struct SomeKey();
struct SomeValue();
fn main() {
let mut m = HashMap::<ByAddress<&SomeKey>, SomeValue>::new();
let t1 = SomeKey();
let t2 = SomeKey();
m.insert(ByAddress(&t1), SomeValue());
assert!(m.get(&ByAddress(&t1)).is_some());
assert!(m.get(&ByAddress(&t2)).is_none());
}