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

Pav*_*dov 17 macros metaprogramming rust rust-macros

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

mca*_*ton 28

这是介绍,以确保无论是在宏调用正确匹配的概念(),[]以及{}对.

例如,对于以下程序:

fn main() {
    println!("Hello world!");
}
Run Code Online (Sandbox Code Playgroud)

令牌树将是:

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

这形成了一个树枝上,简单的记号(;,fn等等)是树叶,以及任何所包围main,()或者[]有一个子树.请注意,{}标记树中不会单独出现:如果不匹配,则(无法匹配(.

例如:

macro_rules! {
    (fn $name:ident $params:tt $body:tt) => { /* … */ }
}
Run Code Online (Sandbox Code Playgroud)

将匹配与上述功能),$name ? main,$params ? ().

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

  • @Tomas 不,它们也可以[命名参数,如`foo=expr`](https://doc.rust-lang.org/std/fmt/index.html#named-parameters) 来替换所有的`"{ foo}"`s. (3认同)
  • 为什么 `println!` 不使用 `expr` 代替?参数不都是表达式吗? (2认同)