如何比较 Rust 中的枚举实例
How to compare Enum instances in Rust
嘿,我正在学习 Rust 并试图弄清楚为什么我不能直接比较一个非常简单的 Enum 的两个实例,我试过使用 matches!
(不起作用)和 #[derive(Eq)]
(只是将问题转发给 impl
这是演示我的问题的片段,它是输出。
#[derive(Debug)]
pub enum MyEnum {
Enum1,
Enum2,
Enum3
}
#[derive(Debug)]
pub enum ThingEnum {
NoOp,
Enum(MyEnum)
}
pub fn test_enum_equate() {
let mut enum1 = Vec::new();
enum1.push(MyEnum::Enum1);
enum1.push(MyEnum::Enum2);
enum1.push(MyEnum::Enum3);
let mut expr = vec![
ThingEnum::NoOp,
ThingEnum::Enum(MyEnum::Enum1),
ThingEnum::Enum(MyEnum::Enum2),
ThingEnum::NoOp,
ThingEnum::Enum(MyEnum::Enum3)
];
for myenum in enum1.iter() {
for entry in expr.iter() {
match entry {
ThingEnum::NoOp => continue,
ThingEnum::Enum(en) => {
// Check if they are the same
println!("matches!({:?}, {:?}) = {}",
myenum, en, matches!(myenum, en)
);
// Need to implement partial eq, WHY?
// println!("{:?} == {:?} -> {}",
// myenum, en, myenum == en
// );
}
}
}
}
}
输出为:
matches!(Enum1, Enum1) = true
matches!(Enum1, Enum2) = true
matches!(Enum1, Enum3) = true
matches!(Enum2, Enum1) = true
matches!(Enum2, Enum2) = true
matches!(Enum2, Enum3) = true
matches!(Enum3, Enum1) = true
matches!(Enum3, Enum2) = true
matches!(Enum3, Enum3) = true
这不是想要的效果。
如果我只是用数字或者字符串,还可以,但是我觉得Enum的用处应该是没有关联值,为什么这么难做?
Rust 等式有两种形式,PartialEq
和 Eq
。每个 Eq
也是 PartialEq
,但反之则不然。具体来说,PartialEq
只要求操作是partial equivalence relation, while Eq
makes the stronger guarantee that the relation is an equivalence relation.
浮点类型 PartialEq
而不是 Eq
的一个很好的例子是浮点类型 f32
和 f64
,它们都有一个特殊的 NaN 值这不等于它自己。在 hashmaps 和二叉树这样的数据结构中,拥有一个不等于自身的值是灾难性的,所以像那些数据结构需要的类型是 Eq
,而 f32
只是 PartialEq
.去尝试做一个HashSet<f32>
。您很快就会 运行 遇到一些编译器错误。
然而,对于你的情况,你真的不需要担心这些。由于您的类型是一个简单的枚举,您可以简单地派生 both PartialEq
和 Eq
.
#[derive(Debug, PartialEq, Eq)]
pub enum MyEnum { ... }
然后 ==
将完全按照您的意愿工作。
嘿,我正在学习 Rust 并试图弄清楚为什么我不能直接比较一个非常简单的 Enum 的两个实例,我试过使用 matches!
(不起作用)和 #[derive(Eq)]
(只是将问题转发给 impl
这是演示我的问题的片段,它是输出。
#[derive(Debug)]
pub enum MyEnum {
Enum1,
Enum2,
Enum3
}
#[derive(Debug)]
pub enum ThingEnum {
NoOp,
Enum(MyEnum)
}
pub fn test_enum_equate() {
let mut enum1 = Vec::new();
enum1.push(MyEnum::Enum1);
enum1.push(MyEnum::Enum2);
enum1.push(MyEnum::Enum3);
let mut expr = vec![
ThingEnum::NoOp,
ThingEnum::Enum(MyEnum::Enum1),
ThingEnum::Enum(MyEnum::Enum2),
ThingEnum::NoOp,
ThingEnum::Enum(MyEnum::Enum3)
];
for myenum in enum1.iter() {
for entry in expr.iter() {
match entry {
ThingEnum::NoOp => continue,
ThingEnum::Enum(en) => {
// Check if they are the same
println!("matches!({:?}, {:?}) = {}",
myenum, en, matches!(myenum, en)
);
// Need to implement partial eq, WHY?
// println!("{:?} == {:?} -> {}",
// myenum, en, myenum == en
// );
}
}
}
}
}
输出为:
matches!(Enum1, Enum1) = true
matches!(Enum1, Enum2) = true
matches!(Enum1, Enum3) = true
matches!(Enum2, Enum1) = true
matches!(Enum2, Enum2) = true
matches!(Enum2, Enum3) = true
matches!(Enum3, Enum1) = true
matches!(Enum3, Enum2) = true
matches!(Enum3, Enum3) = true
这不是想要的效果。
如果我只是用数字或者字符串,还可以,但是我觉得Enum的用处应该是没有关联值,为什么这么难做?
Rust 等式有两种形式,PartialEq
和 Eq
。每个 Eq
也是 PartialEq
,但反之则不然。具体来说,PartialEq
只要求操作是partial equivalence relation, while Eq
makes the stronger guarantee that the relation is an equivalence relation.
浮点类型 PartialEq
而不是 Eq
的一个很好的例子是浮点类型 f32
和 f64
,它们都有一个特殊的 NaN 值这不等于它自己。在 hashmaps 和二叉树这样的数据结构中,拥有一个不等于自身的值是灾难性的,所以像那些数据结构需要的类型是 Eq
,而 f32
只是 PartialEq
.去尝试做一个HashSet<f32>
。您很快就会 运行 遇到一些编译器错误。
然而,对于你的情况,你真的不需要担心这些。由于您的类型是一个简单的枚举,您可以简单地派生 both PartialEq
和 Eq
.
#[derive(Debug, PartialEq, Eq)]
pub enum MyEnum { ... }
然后 ==
将完全按照您的意愿工作。