rust - 如何为具有特殊情况的枚举实现“哈希”?
问题描述
我有这个枚举:
enum MyEnum {
Var1,
Var2(u32),
Var3(u32, u32),
}
我想实现以下行为:
let mut set = HashSet::new();
set.insert(MyEnum::Var1);
set.insert(MyEnum::Var1);
set.insert(MyEnum::Var2(1));
set.insert(MyEnum::Var2(2));
set.insert(MyEnum::Var3(1, 1));
set.insert(MyEnum::Var3(1, 1));
set.insert(MyEnum::Var3(2, 1));
set.insert(MyEnum::Var3(2, 2));
println!("set = {:?}", set);
// set = {Var1, Var2(1), Var2(2), Var3(1, 1), Var3(2, 1)}
也就是说,我想将变体的Hash
行为Var3
专门更改为仅依赖于它的第一个u32
。
重要的是,我不想详尽地列出match
每个枚举变体,因为我想保留所有其他枚举变体的默认行为。因此,据我所知,这些 答案不足以满足我的要求。
我想出的解决方案是这样的:
#[derive(Debug, Eq)]
enum MyEnum {
Var1,
Var2(u32),
Var3(u32, u32),
}
impl PartialEq for MyEnum {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(MyEnum::Var3(a, _), MyEnum::Var3(b, _)) => a == b,
_ => format!("{:?}", self) == format!("{:?}", other),
}
}
}
impl Hash for MyEnum {
fn hash<H: Hasher>(&self, state: &mut H) {
match self {
MyEnum::Var3(a, _) => a.hash(state),
_ => format!("{:?}", self).hash(state)
}
}
}
...我正在寻找反馈/更好的解决方案。
解决方案
衍生板条箱的构建旨在为标准特征提供自动实现,并支持常见的自定义。有了这个板条箱,你可以得到你想要的东西,看起来像这样:
use std::collections::HashSet;
use derivative::Derivative; // 2.2.0
#[derive(Debug, Eq, Derivative)]
#[derivative(PartialEq, Hash)]
enum MyEnum {
Var1,
Var2(u32),
Var3(
u32,
#[derivative(PartialEq="ignore")]
#[derivative(Hash="ignore")]
u32
),
}
fn main() {
let mut set = HashSet::new();
set.insert(MyEnum::Var1);
set.insert(MyEnum::Var1);
set.insert(MyEnum::Var2(1));
set.insert(MyEnum::Var2(2));
set.insert(MyEnum::Var3(1, 1));
set.insert(MyEnum::Var3(1, 1));
set.insert(MyEnum::Var3(2, 1));
set.insert(MyEnum::Var3(2, 2));
println!("set = {:?}", set);
}
set = {Var1, Var3(1, 1), Var3(2, 1), Var2(2), Var2(1)}
在操场上看到它。
推荐阅读
- javascript - 用于 chrome v41 和 ie11 的 Javascript 中的意外令牌 =>
- sql - 为什么子查询会在 group by 查询中抛出错误?
- linux - Centos usermod -a 不要将用户添加到组中
- ios - Xcode 9.X 总是打开 Xcode 8.x 模拟器
- python - 发生错误时运行函数,无需尝试
- java - Android 无法对 sd 卡进行写入和删除操作
- python - 在转换为数据框之前在 Python 中展平嵌套的 Defaultdict 列表
- python - 如何使用这样的高斯函数进行更好的曲线拟合?
- ruby-on-rails - ruby I18n 日期格式在生产一段时间后中断
- c# - 使用 MVVM 的 IsSelected 属性扩展外部对象?