如何为我自己的结构实现Eq和Hash以将它们用作HashMap键?

如何为我自己的结构实现Eq和Hash以将它们用作HashMap键?,hashmap,rust,Hashmap,Rust,我有两个结构,A和B,我想使用一个HashMap。我有一段代码如下: 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 {

我有两个结构,
A
B
,我想使用一个
HashMap
。我有一段代码如下:

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 },
    );
}
impl Eq for Application {}
但是编译器给了我这些错误:

error[E0277]:未满足特性绑定'A:std::cmp::Eq'
-->src/main.rs:16:9
|
16 | map.insert(
|^^^^^特性'std::cmp::Eq'未为'A'实现`
错误[E0277]:未满足特性绑定'A:std::hash::hash'
-->src/main.rs:16:9
|
16 | map.insert(
|^^^^^特性'std::hash::hash'未为'A'实现`
我知道我必须实现这些特性,但在网上搜索了几个小时后,我没有发现任何关于实现这些特性的信息

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

我已经实现了
Hash
特性:

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();
    }
}
但是编译器继续抱怨,这次是关于
Eq

error[E0277]:未满足特性绑定'A:std::cmp::Eq'
-->src/main.rs:16:9
|
16 | map.insert(
|^^^^^特性'std::cmp::Eq'未为'A'实现`

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

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

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

您也可以手动实现它们。如果您想这样做,您应该阅读和上的文档。

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

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 },
    );
}
impl Eq for Application {}
或者,在
应用程序
声明的顶部使用
#[导出(Eq)]


Eq
是受
PartialEq
约束的特性。这意味着您只能在同样实现
PartialEq
的结构上实现它(这里就是这种情况)。通过实现
Eq
,您承诺您的
PartialEq
实现是自反的(请参阅文档了解其含义).

这就是Rust文档所说的编写自己的
哈希实现的方式:

使用std::hash::{hash,Hasher};
结构人{
id:u32,
名称:String,
电话:u64,
}
Person的impl哈希{
fn散列(&self,state:&mut H){
self.id.hash(状态);
self.phone.hash(state);
}
}

来源:

问题是如何编写自己的哈希实现?很少有理由这么做……但正如@fjh所写的,如果您知道要实现哪种特性,请查阅文档。如果遇到问题,请发布您尝试过的代码。您的结构是相互递归的,每个结构都包含一个值为另一种类型的字段。这不能用于com按原样堆。我认为您的
哈希
的impl应该是
self.pid.Hash(state)
。对我来说,调用
finish
是一个错误。