Rust 片段说明符—模式的种类

示例

在中$e:expr,expr称为片段说明符。它告诉解析器该参数$e期望什么样的令牌。Rust提供了多种片段说明符,使输入非常灵活。

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

请注意,文档注释/// 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! {
    ///一些文档评论
    const OPT_INT: i32 as optional;
}

// 以上内容将扩展为:
#[doc="some doc comment"]
const OPT_INT: Option<i32> = None;

按照设定

某些片段说明符要求标记,它后面必须是一个受限制的集合之一,称为“跟随集合”。这为Rust的语法发展提供了一定的灵活性,而又不会破坏现有的宏。

说明符按照设定
expr, stmt=>  ,  ;
ty, path=> , = | ; : > [ { as where
pat=> , = | if in
ident,block,item,meta,tt任何令牌

macro_rules! invalid_macro {
    ($e:expr + $f:expr) => { $e + $f };
//           ^
//           +不在expr的跟随集中,
//           因此编译器将不接受此宏定义。
    ($($e:expr)/+) => { $($e)/+ };
//             ^
//             分隔符`/`不在`expr`的跟随集中
//             因此编译器将不接受此宏定义。
}