Rust宏可以处理多层嵌套表达式吗?

时间:2016-04-19 11:03:27

标签: macros rust

以下代码是对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,但在我的情况下仍然不知道如何实现它。

1 个答案:

答案 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];
}