6 个版本
0.2.1 | 2023年7月19日 |
---|---|
0.2.0 | 2023年7月19日 |
0.1.2 | 2020年7月4日 |
0.1.1 | 2020年7月4日 |
0.1.0 | 2020年7月4日 |
#1912 in 过程宏
每月下载量 703
在 8 个crate中(通过 defile)使用
4KB
::defile
用于“解组”捕获的元变量(因此可能会破坏它们的卫生,因此得名)的辅助过程宏。
当使用需要使用特殊规则(例如 :expr
、:path
、:pat
)进行解析的辅助 macro_rules
宏时,但后来还想进一步检查捕获的变量时,这很有用。
这并不是 macro_rules!
可以独自完成的事情,因为这些所谓的 元变量 被视为一个 不透明的 单个标记(捕获在元变量中的标记序列已被 分组(≈ 括号化),但使用了不可见的括号)。
示例
macro_rules! check_expr {
(
42
) => ({
println!("Got `42`!");
});
(
$($tt:tt)*
) => ({
println!("Did not get `42`. Instead, got the following tokens:\n[");
$(
println!(" `{}`,", stringify!($tt));
)*
println!("]");
});
}
macro_rules! check_all_exprs {(
$(
$expr:expr // use :expr to be able to use `,` as a delimiter
),* $(,)?
) => (
fn main () {
$(
println!("vvvvvvvvvvvvv");
check_expr!($expr);
println!("^^^^^^^^^^^^^\n");
)*
}
)}
check_all_exprs!(42, 1 + 1);
输出
vvvvvvvvvvvvv
Did not get `42`. Instead, got the following tokens:
[
`42`,
]
^^^^^^^^^^^^^
vvvvvvvvvvvvv
Did not get `42`. Instead, got the following tokens:
[
`1 + 1`,
]
^^^^^^^^^^^^^
-
那就是
-
标记
42
不匹配42
! -
话虽如此,表达式
1 + 1
实际上,这正是这种行为的要点:如果我们执行
2 * $expr
,其中$expr
捕获1 + 1
-
但通过执行
macro_rules! check_all_exprs {(
$(
$expr:expr // use :expr to be able to use `,` as a delimiter
),* $(,)?
) => (::defile::defile! { // 👈
fn main () {
$(
println!("vvvvvvvvvvvvv");
check_expr!(@$expr);
// 👆
println!("^^^^^^^^^^^^^\n");
)*
}
})}
我们确实得到
vvvvvvvvvvvvv
Got `42`!
^^^^^^^^^^^^^
vvvvvvvvvvvvv
Did not get `42`. Instead, got the following tokens:
[
`1`,
`+`,
`1`,
]
^^^^^^^^^^^^^
42
匹配了字面值 42,但请注意,这也导致1 + 1
被拆分。因此,如果您要defile
表达式,如2 * @$expr
,您可能不会得到预期的结果!请谨慎使用。
注意事项
目前(1.45.0
),有关 macro_rules!
宏和过程宏之间交互的几个错误可能导致 defile!
和任何其他辅助过程宏拆分非 @
前缀的组。
希望这些错误已经被解决,使得 defile!
的实际实现具有意义。