tt 元变量类型在 Rust 宏中意味着什么?

What does the tt metavariable type mean in Rust macros?

我正在读一本关于 Rust 的书,并开始玩 Rust macros。除了最后一个 - tt 之外,所有元变量类型都在此处进行了解释并提供了示例。按照书中的说法,它是一棵“单令牌树”。我很好奇,它是什么以及它的用途是什么?能举个例子吗?

引入这个概念是为了确保宏调用中的任何内容都能正确匹配 ()[]{} 对。 tt 将匹配任何单个标记 任何一对 parenthesis/brackets/braces 及其内容 .

例如,对于以下程序:

fn main() {
    println!("Hello world!");
}

令牌树将是:

  • fn
  • main
  • ()
  • { println!("Hello world!"); }
    • println
    • !
    • ("Hello world!")
      • "Hello world!"
    • ;

每个都形成一棵树,其中简单标记(fnmain 等)是叶子,任何被 ()[] 或 [=14 包围的东西=] 有一个子树。请注意 ( 不会单独出现在令牌树中:如果不匹配相应的 ).

就不可能匹配 (

例如:

macro_rules! {
    (fn $name:ident $params:tt $body:tt) => { /* … */ }
}

会将上述函数与 $name → main$params → ()$body → { println!("Hello world!"); } 相匹配。

令牌树是要求最低的元变量类型:它匹配任何东西。它通常用于具有“不太关心”部分的宏,尤其是具有“头”和“尾”部分的宏。例如,println! 宏有一个匹配 ($fmt:expr, $($arg:tt)*) 的分支,其中 $fmt 是格式字符串,而 $($arg:tt)* 表示“所有其余”,只是转发到 format_args!.这意味着 println! 不需要知道实际格式并与之进行复杂的匹配。