如何解决过滤迭代器中与模式匹配的值的惯用方式
在下面的示例(here is the Rust playground)中,我需要在迭代器中过滤与特定模式匹配的值。
我发现的一种方法是使用match
返回Option
中的filter_map
:
#[derive(copy,Clone,Debug)]
struct Entity(i32);
enum Event {
EntityInserted(Entity),EntityRemoved(Entity),}
fn main() {
let [entity1,entity2] = [Entity(1),Entity(2)];
let events = vec![
Event::EntityInserted(entity1),Event::EntityRemoved(entity1),Event::EntityInserted(entity2),];
let inserted_entities: Vec<_> = events
.iter()
.filter_map(|event| match event { // <---
Event::EntityInserted(entity) => Some(entity),// <--- Those lines
_ => None,// <--- here
}) // <---
.collect();
dbg!(inserted_entities);
}
是否有更惯用的方式来发生这种行为?
解决方法
对于filter_map
,我认为这是要走的路。
奇怪的是,昨天我写了一个宏,如果Some
是“成功”,则生成一个if
,否则会得出None
:
macro_rules! if_then_some {
($cond: expr,$val: expr) => {
if $cond { Some($val) } else { None }
};
(let $pattern:pat = $expr: expr,$val: expr) => {
if let $pattern = $expr { Some($val) } else { None }
};
}
就目前而言,它可用于检查bool
-条件和if let
-条件。在您的情况下,可以使用like this:
let inserted_entities: Vec<_> = events
.iter()
.filter_map(|event|
if_then_some!(let Event::EntityInserted(entity)=event,entity)
)
.collect();
如果这是“惯用的”,这是有争议的,但是恕我直言,它简洁而又易读。
有点题外话:另一方面,每当我看到if let
带有Option
或Result
以外的其他内容时,我都会警惕如果我添加了在这种情况下应检查的新变体,则编译器不会警告我。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。