rust - 哈希特征不适用于枚举中的 Rc<RefCell<T>>

标签 rust hash enums traits refcell

我定义了一个结构体MyData并实现PartialEqHash手动为其添加特征。

我定义了一个枚举,其中包括 Rc<MyData>Rc<RefCell<MyData>> .

我想要导出PartialEqHash对于枚举,但失败了:

  1. PartialEqHash两者都适用于 Rc<MyData> ;
  2. PartialEq适用于 Rc<RefCell<MyData>>也是;
  3. 但是Hash不适用于 Rc<RefCell<MyData>> !

我有 2 个问题:

  1. 为什么?为什么只有Hash仅适用于 Rc<RefCell<MyData>>

  2. 如何解决?

    我无法实现Hash对于 Rc<RefCell<MyData>> 。经过搜索后,我找到了一种方法:定义一个新的包装结构,例如 struct RRWrapper<T> (Rc<RefCell<T>>) ,然后执行 Hash为此RRWrapper 。但这会带来很多代码。有惯用的方法吗?我认为这是一般用法。

提前致谢,

PS:在我的程序的真实代码中,只有 Rc<RefCell<MyData>>在枚举中,但没有 Rc<MyData> 。我把Rc<MyData>这里只是为了比较。 PS2:在我程序的真实代码中,有不止一个Rc<RefCell<T>>在枚举中。


原始源代码:

use std::rc::Rc;
use std::cell::RefCell;
use std::hash::{Hash, Hasher};

struct MyData {
    i: i64,
}

impl Hash for MyData {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.hash(state);
    }
}
impl PartialEq for MyData {
    fn eq(&self, other: &Self) -> bool {
        self == other
    }
}

#[derive(PartialEq, Hash)]
enum MyEnum {
    INT(i64),
    STR(String),
    MYDATA1(Rc<MyData>), // OK both
    MYDATA2(Rc<RefCell<MyData>>), // OK for PartialEq but not for Hash
}

fn main() {
}

错误:

20  | #[derive(PartialEq, Hash)]
    |                     ---- in this derive macro expansion
...
25  |     MYDATA2(Rc<RefCell<MyData>>), // OK for PartialEq but not for Hash
    |             ^^^^^^^^^^^^^^^^^^^ the trait `Hash` is not implemented for `RefCell<MyData>`
    |
    = note: required because of the requirements on the impl of `Hash` for `Rc<RefCell<MyData>>`
    = note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)

struct RRWrapper的源代码:


#[derive(Debug, PartialEq, Eq)]
pub struct RRWrapper<T: Hash+PartialEq+Eq>(Rc<RefCell<T>>);

impl<T: Hash+PartialEq+Eq> Deref for RRWrapper<T> {
    type Target = Rc<RefCell<T>>;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}
impl<T: Hash+PartialEq+Eq> Hash for RRWrapper<T> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.0.borrow().hash(state);
    }
}
impl<T: Hash+PartialEq+Eq> Clone for RRWrapper<T> {
    fn clone(&self) -> Self {
        RRWrapper(self.0.clone())
    }
}
impl<T: Hash+PartialEq+Eq> RRWrapper<T> {
    pub fn new(inner: T) -> Self {
        RRWrapper(Rc::new(RefCell::new(inner)))
    }
}

最佳答案

Why? Why only the Hash does not work only for Rc<RefCell>?

如果您考虑一下,就会发现 Hash 没有为 RefCell 实现。既然它是内部可变性的抽象,那么可能改变的东西的哈希值可能是什么?一般来说,可变的东西不适合作为 Hash 对象,因此。

How to fix it?

正如你所做的那样。对你真正想要的事情负责。将其实现为包装器。

关于rust - 哈希特征不适用于枚举中的 Rc<RefCell<T>>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69557849/

相关文章:

authentication - 在.NET Core 2.0中实现bcrypt

rust - 有没有办法为类似函数的 proc 宏提供通用参数?

rust - 25519-dalek中的主要新增功能?

swift - 根据以特定字符结尾的哈希键选择存储的值

java - 通过 HashMap 进行迭代(复杂性)

java - 定义一个与其所在类同名的枚举

C# "Enum"序列化 - 反序列化为静态实例

c++ - C++ 中枚举和 lambda 的映射

rust - 我可以在静态向量中包含非静态结构吗

rust - 在 Rust 中与生命周期的子类型关系作斗争