【问题标题】:How do I match either a path or a tt in a macro?如何匹配宏中的路径或 tt?
【发布时间】:2018-12-12 14:17:49
【问题描述】:

我正在 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 宏,所以我可能会遗漏一些东西。

【问题讨论】:

  • 仅供参考:test_macro!("it", (foo::test()), "work"); 已被接受。
  • 有什么理由不使用expr 而不是tt

标签: macros rust


【解决方案1】:

我认为你的逻辑有错误。作为mcarton noted in the comments,你的宏应该是( $( $x: expr ),* ) 而不是( $( $x: tt ),* )。也就是说,使用表达式而不是标记树。

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

【讨论】:

    猜你喜欢
    • 2016-07-10
    • 1970-01-01
    • 2020-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多