以下代码是对macro_rule!
限制的简单测试。它正确打印[1, 2]
作为目标。
macro_rules! test {
($target:tt) => {
println!("{:?}", $target);
};
($target:tt, $($rest:tt),*) => {
test!($target)
};
([$target:tt, $($inner_rest:tt),*],$($rest:tt),*) => {
test!($target)
}
}
fn main() {
test![[1, 2], [[5, 6], 3], 4];
}
但是,如果我将[[1,2]
更改为[[1,2],3]
,编译器会抱怨:
<anon>:16:15: 16:16 error: mismatched types:
expected `[_; 2]`,
found `_`
(expected array of 2 elements,
found integral variable) [E0308]
<anon>:16 test![[[1,2],3],[[5,6],3],4];
^
<std macros>:2:25: 2:56 note: in this expansion of format_args!
<std macros>:3:1: 3:54 note: in this expansion of print! (defined in <std macros>)
<anon>:4:5: 4:30 note: in this expansion of println! (defined in <std macros>)
<anon>:7:6: 7:20 note: in this expansion of test! (defined in <anon>)
<anon>:16:2: 16:31 note: in this expansion of test! (defined in <anon>)
<anon>:16:15: 16:16 help: see the detailed explanation for E0308
error: aborting due to previous error
playpen: application terminated with error code 101
有没有办法让宏递归处理括号并打印第一项?我研究过the example given by the Rust documentation,但在我的情况下仍然不知道如何实现它。
答案 0 :(得分:2)
你要求它解析一个表达式,这正是它尝试做的事情。
它看到的第一件事是[[1, 2], 3]
,它是无效的,因为它是一个数组文字,其中第一个元素的类型为[i32; 2]
,第二个元素的类型为i32
。所以,它失败了。
如果你想宏来处理递归语法,你将不得不写它来处理它。我不知道你要做什么(“处理括号”如何?),所以我不能提供一个具体的例子。尝试在明确处理[[$($stuff:tt)*] ...
的现有规则之前添加额外规则。规则从上到下进行处理,因此您需要先将最具体的规则放在最前面。以下打印出[1, 2]
:
macro_rules! test {
([$target:tt, $($inner_rest:tt),*], $($rest:tt),*) => {
test!($target)
};
($target:tt) => {
println!("{:?}", $target);
};
($target:tt, $($rest:tt),*) => {
test!($target)
};
}
fn main() {
test![[[1,2],3],[[5,6],3],4];
}