我想在迭代器上应用filter
并且我想出了这个并且它可以工作,但是它非常详细:
.filter(|ref my_struct| match my_struct.my_enum { Unknown => false, _ => true })
我宁愿写这样的东西:
.filter(|ref my_struct| my_struct.my_enum != Unknown)
这给了我一个编译错误
binary operation `!=` cannot be applied to type `MyEnum`
是否有替代冗长模式匹配的替代方法?我寻找一个宏但找不到合适的宏。
答案 0 :(得分:40)
首先,您可以使用PartialEq
特征,例如#[derive]
:
#[derive(PartialEq)]
enum MyEnum { ... }
那么你的理想"变体将按原样运行。但是,这要求MyEnum
的内容也实现PartialEq
,这并不总是可行/想要的。
其次,你可以自己实现一个宏,就像这样(虽然这个宏不支持所有类型的模式,例如,替代方案):
macro_rules! matches(
($e:expr, $p:pat) => (
match $e {
$p => true,
_ => false
}
)
)
然后你会像这样使用它:
.filter(|ref my_struct| !matches!(my_struct.my_enum, Unknown))
有an RFC将这样的宏添加到标准库中,但仍在讨论中。
答案 1 :(得分:3)
我使用模式匹配,但是我将它移动到枚举上的方法,以便过滤器闭包更整洁:
#[derive(Debug)]
enum Thing {
One(i32),
Two(String),
Unknown,
}
impl Thing {
fn is_unknown(&self) -> bool {
match *self {
Thing::Unknown => true,
_ => false,
}
}
}
fn main() {
let things = vec![Thing::One(42), Thing::Two("hello".into()), Thing::Unknown];
for t in things.iter().filter(|s| !s.is_unknown()) {
println!("{:?}", t);
}
}
另见:
答案 2 :(得分:0)
您可以将if let Some(x) = option { then }
习语与相同的if let
构造一起使用,而无需进行破坏:
if let Unknown = my_struct.my_enum { false } else { true }