Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

rust - How to implement Eq and Hash for my own structs to use them as a HashMap key?

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...