理解 Rust 的 `macro_rules!` 宏中的 `tt`

Understanding `tt` in Rust's `macro_rules!` macros

我无法理解 Rust 的 macro_rules! 宏中的 tt 到底是什么。

开始,我认为

tt will match any single token or any pair of parenthesis/brackets/braces with their content.

然而,下面的例子似乎并没有遵循这个规则:

macro_rules! foo {
  (content: $content:tt) => {
    mod foo {
      $content
    }
  }
}

foo! (
  content: {
    pub fn main() {
      println!("Hello");
    }  
  }
);

我希望 ttcontent: 之后的 {} 中包含的所有内容匹配,并且宏调用的结果将是

mod foo {
  pub fn main() {
    println!("Hello");
  }
}

相反,我收到以下错误消息:

error: expected item, found `{`
  --> src/main.rs:10:12
   |
10 |   content: {
   |            ^ expected item

这里出了什么问题?另外,为什么 Rust 在我告诉它期待 tt 时告诉我它期待 item

tt 在这里按预期工作。您的宏调用如下:

foo! (
  content: {
    pub fn main() {
      println!("Hello");
    }  
  }
);

$content是这样的:

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

所以,结果是这样的:

mod foo {
    { // <-- Error occurs here
        pub fn main() {
            println!("Hello");
        }  
    }
}

您不能在 mod 声明中直接使用另一组花括号。

让您的代码正常工作的解决方案是将 $content 直接放在 mod foo 之后,但我想您已经看到了:

macro_rules! foo {
  (content: $content:tt) => {
    mod foo $content
  }
}

foo! (
  content: {
    pub fn main() {
      println!("Hello");
    }  
  }
);

Playground