Rust 宏:大括号和带括号的宏体有什么区别?

Rust macros: What is the difference between braced and parenthesized macro bodies?

Afaik, Rust 中的宏声明语法如下:

macro_rules! <name> {
    (<pattern>) => {
        <implementation>
    };
}

但是我发现了一个版本,其中正文包含在括号中而不是 Rust by Example 中的大括号中:

macro_rules! <name> {
    (<pattern>) => (
        <implementation>
    )
}

另请注意缺少尾随分号。我最好的猜测是这与这个宏使用的尾递归有关,但我用括号括起来的宏体和用大括号括起来的宏体之间的官方区别是什么?

(..)[..]{..}的宏定义没有区别,见reference documentation=> 右侧块的语法是 DelimTokenTree。我猜想拥有所有三种变体的动机是允许宏的模式包含任何两种类型的大括号。

分号是可选的,如您在 MacroRules 语法中所见。您甚至可以对宏的外部使用 (..)[..]

当你invoke the macro时,你也可以使用这三种口味,但是每一种都有使用限制:

When used as an item or a statement, the MacroInvocationSemi form is used where a semicolon is required at the end when not using curly braces.

macro_rules 中的分支只需用 ; 分隔即可。尾随分号在那里是可选的。在macro_rulesformal grammar中,这是由

描述的
MacroRules :
   MacroRule ( ; MacroRule )* ;?

此处的语法类似于正则表达式。规则列表至少是一个规则,后跟任意数量的分号-MacroRule 对。所有这些后跟一个可选的分号。

选择(){}[]实际上在这里根本不重要。这三种都是接受的解析 DelimTokenTree

的方法
DelimTokenTree :
     ( TokenTree* )
   | [ TokenTree* ]
   | { TokenTree* }

这意味着 DelimTokenTree 将被相同地解析,无论它被 ()[]{}.

包围

特别是,您链接的宏与 all six combinations 选择方括号和尾随分号的效果相同。