如何在宏中匹配路径或tt?

时间:2018-12-12 14:17:49

标签: macros rust

我正在构建我认为在Rust中相当简单的宏,以接受任意参数列表(stransi_term::Style对象)。

我的宏看起来像这样:

macro_rules! test_macro {
    ( $( $x: tt ),* ) => (
        $(
            print!("{} ", $x);
        )*
        println!();
    )
}

作为一个最小的工作示例,我还定义了一个模块和一个函数:

mod foo {
    pub fn test() -> &'static str {
        "doesn't"
    }
}

fn test() -> &'static str {
    "doesn't"
}

该宏可用于简单的调用,例如

test_macro!("it", "works");

但是,如果我尝试更复杂的操作,则会出现编译器错误:

fn test() -> &'static str {
    "doesn't"
}
test_macro!("it", test(), "work");

产生

error: no rules expected the token `(`
   |
24 |     test_macro!("it", test(), "work");
   |                           ^
   |                           |
   |                           help: missing comma here

test_macro!("it", foo::test(), "work");

产生

error: no rules expected the token `::`
   |
25 |     test_macro!("it", foo::test(), "work");
   |                          ^^

Rust Playground example

这是我第一次使用Rust宏,因此我可能会遗漏其他内容。

1 个答案:

答案 0 :(得分:1)

我认为您的逻辑有误。与mcarton noted in the comments一样,您的宏应为( $( $x: expr ),* )而不是( $( $x: tt ),* )。也就是说,使用表达式而不是令牌树。

使用宏打印内容的方式不适用于令牌树中存在的某些可能值。我相当确定您无法调用您的宏可能允许的print!("{}", std::os)