hash - 如何对使用rust 的单元结构执行 `Hash`?

标签 hash equality rust

我想实现一种thing,可以唯一标识,除此之外,它不包含其他字段。它有点像 ruby​​ 中的 BasicObject 或 java 中的 Object

我添加了一个 PartialEq 特征。

struct Thing;
impl PartialEq for Thing {
  fn eq(&self, other: &Thing) -> bool {
    unsafe {
      self as *const Thing == other as *const Thing
    }
  }
}

现在,我想让它可以被散列,问题是我如何实现 Hash没有文件的单元结构的特征?或者,我应该向它添加某种 object_id 吗?

最佳答案

您不能依赖指针地址来确定 Rust 中单元结构的唯一性,例如以下代码将打印两次相同的地址:

struct Foo;

fn main() {
    let x = Foo;
    let y = Foo;
    println!("{}", &x as *const _);
    println!("{}", &y as *const _);
}

你需要让它们在内存中至少占据一个字节,例如给它们一个你从不使用的字段:

struct Thing {
    x: u8;
}

impl Thing {
    fn new() -> Thing {
        Thing { x: 0u8 }
    }
}

然后,一个简单的方法是继续沿原路行驶,并使用内存中对象的地址作为哈希的基值:

use std::hash::{hash,Hash};
use std::hash::sip::SipState;

struct Thing;

impl Hash for Thing {
    fn hash(&self, state: &mut SipState) {
        let addr = self as *const Thing as u64;
        addr.hash(state);
    }
}

fn main() {
    let f = Thing;
    println!("{}", hash(&f));
}

注:类型转换&Thing*const Thing (然后到 u64 )不是不安全的,所以你不需要 unsafe{}阻止您的 PartialEq 实现。

关于hash - 如何对使用rust 的单元结构执行 `Hash`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26311953/

相关文章:

ruby - 为什么 double splat 仅适用于符号键?

variables - 为什么存在下划线前缀变量?

javascript - 我如何获取从wasm(rust)到js的静态mut的地址?

java - 如何在 Java 中比较字符串?

types - Rust 中的类型级映射

.net - 平衡的树状数据结构,可调整为素数大小

ruby - 如何将多个值推送到同一个哈希键

ruby - 计算 Ruby 中每个唯一对象属性的对象总和

C++ 对继承类强制执行条件

c# - TypeDelegator 平等不一致?