匹配下划线而不是宏中的标识
Match an underscore instead of ident in macro
我正在创建一个匹配两个表达式和一个标识符的宏。如果不需要标识符,我希望能够忽略它,但是如果我在那里使用 _
,编译器似乎会抱怨。
我的宏:
macro_rules! if_some {
($x:expr, $id:ident, $expr:expr) => {
match $x {
None => None,
Some($id) => Some($expr),
}
};
}
我想做什么:
if_some!(obtain_an_option(), x, do_something_with(x))
和
if_some!(obtain_an_option(), _, do_something())
第二次调用失败。
我通过定义不接收标识符的第二个宏 if_some_!
解决了这个问题(我也无法使用第二个模式)。我确定有一种方法可以说“这里接受一个标识符或只是 _
.
也许已经有一个 macro/function 了(比如 Option::map
现在我想到了)...不过到现在还是不错的。
最简单的方法是添加与下划线匹配的第二个臂:
macro_rules! if_some {
($x:expr, _, $expr:expr) => {
match $x {
None => None,
Some(_) => Some($expr),
}
};
($x:expr, $id:ident, $expr:expr) => {
match $x {
None => None,
Some($id) => Some($expr),
}
};
}
而且,是的,这听起来像是您想要 Option::map
。
Option::map
似乎是这个特定问题的最佳解决方案,但是当你真的需要一个宏来期望 idents 和 _
作为模式时,你也可以使用 $p:pat
片段。该片段当然接受更广泛的模式,如 (ref x, y)
,但通常这是可以接受的。
macro_rules! if_some {
($x:expr, $p:pat, $expr:expr) => {
match $x {
None => None,
Some($p) => Some($expr),
}
};
}
fn main() {
println!("{:?}", if_some!(Some(12), x, x + 1)); // Some(13)
println!("{:?}", if_some!(Some(12), _, 1)); // Some(1)
}
我正在创建一个匹配两个表达式和一个标识符的宏。如果不需要标识符,我希望能够忽略它,但是如果我在那里使用 _
,编译器似乎会抱怨。
我的宏:
macro_rules! if_some {
($x:expr, $id:ident, $expr:expr) => {
match $x {
None => None,
Some($id) => Some($expr),
}
};
}
我想做什么:
if_some!(obtain_an_option(), x, do_something_with(x))
和
if_some!(obtain_an_option(), _, do_something())
第二次调用失败。
我通过定义不接收标识符的第二个宏 if_some_!
解决了这个问题(我也无法使用第二个模式)。我确定有一种方法可以说“这里接受一个标识符或只是 _
.
也许已经有一个 macro/function 了(比如 Option::map
现在我想到了)...不过到现在还是不错的。
最简单的方法是添加与下划线匹配的第二个臂:
macro_rules! if_some {
($x:expr, _, $expr:expr) => {
match $x {
None => None,
Some(_) => Some($expr),
}
};
($x:expr, $id:ident, $expr:expr) => {
match $x {
None => None,
Some($id) => Some($expr),
}
};
}
而且,是的,这听起来像是您想要 Option::map
。
Option::map
似乎是这个特定问题的最佳解决方案,但是当你真的需要一个宏来期望 idents 和 _
作为模式时,你也可以使用 $p:pat
片段。该片段当然接受更广泛的模式,如 (ref x, y)
,但通常这是可以接受的。
macro_rules! if_some {
($x:expr, $p:pat, $expr:expr) => {
match $x {
None => None,
Some($p) => Some($expr),
}
};
}
fn main() {
println!("{:?}", if_some!(Some(12), x, x + 1)); // Some(13)
println!("{:?}", if_some!(Some(12), _, 1)); // Some(1)
}