macros - 有没有办法将 match 语句的主体与 Rust 宏匹配?
问题描述
我有这样的想法:
macro_rules! mymatch {
($obj:ident, ($matcher:tt => $result:tt),*) => {
match $obj {
$matcher
},
}
}
mymatch! {
x,
10 => "Ten",
n if n < 5 => "Less than 5"
}
我不想重新实现该match
声明,但我确实想在两边添加额外的东西。但是,我不知道如何匹配 match 语句的内容。
解决方案
您的语法有一些问题。如果要匹配重复的模式,则需要以 a 开始分组$
,如下所示$($matcher:tt => $result:tt),*
:
接下来,您可能想要匹配的不仅仅是标识符,因为任何表达式都可以匹配,因此将其更改为expr
. 左边=>
你会想要一个pat
(模式),而不是一个tt
. 令牌树是通用的,但例如, inn if n < 5
将匹配 5 个单独的令牌 - n
, if
, n
, <
, 5
- 并且您通常只有在没有其他方法工作时才会依赖它。结果也是如此 - 这也应该是一个expr
(表达式)。
现在忽略if < 5
守卫,您可以匹配以下内容:
my_match! {
x,
10 => "Ten",
_ => "something else"
}
使用以下宏:
macro_rules! my_match {
($obj:expr, $($matcher:pat => $result:expr),*) => {
match $obj {
$($matcher => $result),*
}
}
}
守卫很烦人,因为它们是可选的,但?
量词还不稳定。相反,您必须使用*
(0 或更多),即使它在技术上会比您需要的更多匹配。
完整的宏是:
macro_rules! my_match {
($obj:expr, $($matcher:pat $(if $pred:expr)* => $result:expr),*) => {
match $obj {
$($matcher $(if $pred)* => $result),*
}
}
}
并支持这种用法:
let x = 7;
let s = my_match! {
x,
10 => "Ten",
n if x < 5 => "Less than 5",
_ => "something else"
};
println!("s = {:?}", s); // "Something else"
块也是expr
,所以这也是有效的:
my_match! {
x,
10 => "Ten",
n if x < 5 => {
println!("it was {}", n);
"Less than 5"
},
_ => "something else"
};
推荐阅读
- sql-server - 在 SQL Server 的 Departments 表中更新每个部门的 NoOfStudents 的最佳方法是什么?
- python - 如何让我的爆炸附加在我的敌人 x 和 y 上?游戏
- c++ - 每个类的函数在该类的对象中是否有函数指针?
- vba - 获取符号包含名称
- python - 在熊猫上使用 for 循环绘图
- microsoft-graph-api - 从外部系统调用微软团队的用户
- nsubstitute - Nsubstitute 是否可以检查 void 方法的参数值
- java - 如何防止 AWS Lambda 从 SQS 队列中删除消息
- python - 如何运行具有实时输出的python子进程?
- node.js - ReactJS:启动服务器时出错