rust macro_rules重复未生成预期的内标识类型

wljmcqd8  于 2023-03-08  发布在  Mac
关注(0)|答案(1)|浏览(121)

我试图在宏中匹配用户提供的列表,但是repeat-pattern不匹配相同的分支,这取决于我是直接在单个项目上调用宏,还是从repeat块调用它。
输入代码(playground link):

macro_rules! foo {
    ($a:ident) => { println!("Printing ident"); };
    ($b:literal) => { println!("Printing literal"); };
    ([ $($something:expr),+ $(,)? ]) => {
            println!("Printing repeat");
            $(
                foo!($something);
            )*
    };
    ($catch_all:expr) => { println!("Printing expr"); };
}

fn main() {
    foo!(baz);
    foo!([1, "asd"]);
    foo!([baz]);
}

输出:

Printing ident
Printing repeat
Printing literal
Printing literal
Printing repeat
Printing expr

第一行打印"ident"行,最后一行打印"expr"行(另一行只是为了表明我想做的事情是有效的,至少对文字是有效的)。
这种行为的问题是,我还期望用户提供expr,现在我无法区分原始ident和expr。
更具体地说,我希望能够编写foo!(["a literal", some_ident, complex_stuff!()]),其中对所有三个参数的处理方式不同。

ui7jx7zq

ui7jx7zq1#

要避免强制使用令牌类型,可以匹配类型tt

macro_rules! foo {
    ($a:ident) => { println!("Printing ident"); };

    ($b:literal) => { println!("Printing literal"); };

    ([ $($something:tt),+ $(,)? ]) => {
            println!("Printing repeat");
            $(
                foo!($something);
            )*
    };

    ($catch_all:expr) => { println!("Printing expr"); };
}

main的结果如下。

Printing ident
Printing repeat
Printing literal
Printing literal
Printing repeat
Printing ident

相关问题