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

Rev*_*ron 11 hashmap rust

我有两个结构,A而且B,我想用一个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 },
    );
}
Run Code Online (Sandbox Code Playgroud)

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

错误:core::cmp::Eq类型A[E0277]
错误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();
    }
}
Run Code Online (Sandbox Code Playgroud)

我也提出了一个建议PartialEq:

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

但编译器抱怨Eq:

错误:core::cmp::Eq该类型没有实现特征app::Application

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

Chr*_*vén 12

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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


bar*_*jak 11

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

impl Eq for Application {}
Run Code Online (Sandbox Code Playgroud)

或者,#[derive(Eq)]Application声明之上使用

Eq是一个受到约束的特质PartialEq.这意味着您只能在也实现的结构上实现它PartialEq(这是这里的情况).通过实施Eq,您承诺您的实现PartialEq是反身的(请参阅文档了解它的含义).


fjh*_*fjh 10

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

#[derive(PartialEq, Eq, Hash)]
pub struct A {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

您也可以手动实现它们.如果你想这样做,你应该阅读有关特征的文档,EqHash.

  • 问题是如何编写自己的哈希实现? (3认同)
  • 很少有理由这么做......但正如@fjh所写,如果你知道要实现哪种特性,请查阅文档.如果遇到麻烦,请发布您尝试过的代码. (2认同)