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! 的实际实现具有意义。