我想实现一种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/