如何为我自己的结构实现Eq和Hash以在HashMap中使用它们?

时间:2015-08-05 14:39:33

标签: hashmap rust

我有两个结构,AB,我想使用HashMap<A, B>。我有一段这样的代码:

use std::collections::HashMap;

pub struct A {
    x: i32,
    y: i32,
    title: String,
    b_obj: B,
}

pub struct B {
    a: u32,
    b: u32,
    a_obj: A,
}

fn main() {
    let map = HashMap::new();
    map.insert(
        A {
            x: 10,
            y: 20,
            title: "test".to_string(),
        },
        B { a: 1, b: 2 },
    );
}

但是编译器给了我这些错误:

  

错误:core::cmp::Eq [E0277]类型未实现特性A   错误:未实现特征core::hash::Hash   类型A [E0277]

我知道我必须实现这些特性,但经过几个小时的网络搜索,我发现没有任何关于实施它们的信息。

我的实际代码更复杂,我的结构包含其他结构(我编辑了代码)。

我已实施Hash特征:

impl Hash for Application {
    fn hash<H>(&self, state: &mut H)
    where
        H: Hasher,
    {
        state.write_u32(self.pid);
        state.finish();
    }
}

我也为PartialEq做了一个impl:

impl PartialEq for Application {
    fn eq(&self, other: &Application) -> bool {
        self.pid == other.pid
    }
}

但编译器抱怨Eq

  

错误:未对类型core::cmp::Eq

实施特征app::Application

如何实施Eq?为什么文档中没有实现?

3 个答案:

答案 0 :(得分:8)

您可以让编译器通过在结构声明之前插入以下内容来为您派生这些实例:

#[derive(PartialEq, Eq, Hash)]
pub struct A {
    // ...
}

您也可以手动实施它们。如果您想这样做,请阅读traitsEqHash上的文档。

答案 1 :(得分:8)

Eq就是我们所说的标记特征:它本身没有方法,它只是程序员表达结构验证某个属性的一种方式。您可以像这样实现它:

impl Eq for Application {}

或者,在#[derive(Eq)]声明

之上使用Application

Eq是由PartialEq约束的特征。这意味着您只能在也实现PartialEq的结构上实现它(这是这里的情况)。通过实施Eq,您承诺PartialEq的实施具有反身性(请参阅文档了解其含义)。

答案 2 :(得分:2)

这就是 Rust 文档所说的您编写自己的 Hash 实现:

use std::hash::{Hash, Hasher};

struct Person {
    id: u32,
    name: String,
    phone: u64,
}

impl Hash for Person {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.id.hash(state);
        self.phone.hash(state);
    }
}

来源:https://doc.rust-lang.org/std/hash/trait.Hash.html