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

时间:2016-10-28 09:24:52

标签: macros rust metaprogramming rust-macros

我正在读一本关于Rust的书,并开始玩Rust macros。所有元变量类型都在那里解释并有示例,除了最后一个 - tt。根据这本书,它是一个“单一的标记树”。我很好奇,它是什么,它用于什么?你能举个例子吗?

1 个答案:

答案 0 :(得分:22)

这是为了确保宏调用中的任何内容正确匹配()[]{}对而引入的概念。

例如,对于以下程序:

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

令牌树将是:

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

这会形成一个树,其中简单的令牌(fnmain等)是树叶,()[]{}包围的任何内容都包含一个子树。请注意,(不会单独出现在令牌树中:如果不匹配相应的(,则无法匹配)

例如:

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

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

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