片段说明符种类的模式

$e:expr 中,expr 被称为片段说明符。它告诉解析器参数 $e 期望的是什么类型的标记。Rust 提供了各种片段说明符,允许输入非常灵活。

描述 例子
ident 识别码 xfoo
path 合格的名称 std::collection::HashSetVec::new
ty 类型 i32&TVec<(char, String)>
expr 表达 2+2f(42)if true { 1 } else { 2 }
pat 图案 _c @ 'a' ... 'z'(true, &x)Badger { age, .. }
stmt 声明 let x = 3return 42
block 大括号区块 { foo(); bar(); }{ x(); y(); z() }
item 项目 fn foo() {}struct Bar;use std::io;
meta 属性内部 cfg!(windows)doc="comment"
tt 令牌树 +foo5[?!(???)]

请注意,文档注释/// comment 被视为与 #[doc="comment"] 相同的宏。

macro_rules! declare_const_option_type {
    (
        $(#[$attr:meta])*
        const $name:ident: $ty:ty as optional;
    ) => {
        $(#[$attr])*
        const $name: Option<$ty> = None;
    }
}

declare_const_option_type! {
    /// some doc comment
    const OPT_INT: i32 as optional;
}

// The above will be expanded to:
#[doc="some doc comment"]
const OPT_INT: Option<i32> = None;

按照设定

某些片段说明符需要在其后面的令牌必须是受限集之一,称为跟随集。这为 Rust 的语法提供了一些灵活性,可以在不破坏现有宏的情况下进行演变。

按照设定
exprstmt => , ;
typath => , = | ; : > [ { as where
pat => , = | if in
identblockitemmetatt 任何令牌
macro_rules! invalid_macro {
    ($e:expr + $f:expr) => { $e + $f };
//           ^
//           `+` is not in the follow set of `expr`,
//           and thus the compiler will not accept this macro definition.
    ($($e:expr)/+) => { $($e)/+ };
//             ^
//             The separator `/` is not in the follow set of `expr`
//             and thus the compiler will not accept this macro definition.
}