问题
I have two structs, A
and B
, and I want to use a HashMap<A, B>
. I have a piece of code like this:
use std::collections::HashMap;
pub struct A {
x: i32,
y: i32,
title: String,
}
pub struct B {
a: u32,
b: u32,
}
fn main() {
let map = HashMap::new();
map.insert(
A {
x: 10,
y: 20,
title: "test".to_string(),
},
B { a: 1, b: 2 },
);
}
But the compiler gives me these errors:
error[E0277]: the trait bound `A: std::cmp::Eq` is not satisfied
--> src/main.rs:16:9
|
16 | map.insert(
| ^^^^^^ the trait `std::cmp::Eq` is not implemented for `A`
error[E0277]: the trait bound `A: std::hash::Hash` is not satisfied
--> src/main.rs:16:9
|
16 | map.insert(
| ^^^^^^ the trait `std::hash::Hash` is not implemented for `A`
I know that I must implement these traits, but after hours of searching the web, I have found nothing about implementing them.
My actual code is more complicated, and my structs contain other structs (I've edited the code).
I've implemented the Hash
trait:
impl std::hash::Hash for A {
fn hash<H>(&self, state: &mut H)
where
H: std::hash::Hasher,
{
state.write_i32(self.x);
state.finish();
}
}
I made an implementation for PartialEq
also:
impl PartialEq for A {
fn eq(&self, other: &A) -> bool {
self.x == other.x
}
}
But the compiler continues to complain, this time about Eq
:
error[E0277]: the trait bound `A: std::cmp::Eq` is not satisfied
--> src/main.rs:16:9
|
16 | map.insert(
| ^^^^^^ the trait `std::cmp::Eq` is not implemented for `A`
How can I implement Eq
? Why is there no implementation in the docs?
回答1:
Eq
is what we call a marker trait: it has no method on its own, it is just a way for the programmer to express that the struct verifies a certain property. You can implement it like this:
impl Eq for Application {}
Or alternatively, use #[derive(Eq)]
on top of the Application
declaration
Eq
is a trait bound by PartialEq
. This means that you can implement it only on structs that also implement PartialEq
(which is the case here). By implementing Eq
, you make the promise that your implementation of PartialEq
is reflexive (see the docs for what it means).
回答2:
You can have the compiler derive these instances for you by inserting the following before your struct declaration:
#[derive(PartialEq, Eq, Hash)]
pub struct A {
// ...
}
You could also implement them manually instead. If you want to do that, you should read the documentation on traits, Eq and Hash.
来源:https://stackoverflow.com/questions/31835647/how-to-implement-eq-and-hash-for-my-own-structs-to-use-them-as-a-hashmap-key