片段说明符种类的模式
在 $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! {
/// 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 的语法提供了一些灵活性,可以在不破坏现有宏的情况下进行演变。
| 符 | 按照设定 |
|---|---|
expr,stmt |
=> , ; |
ty,path |
=> , = | ; : > [ { as where |
pat |
=> , = | if in |
ident,block,item,meta,tt |
任何令牌 |
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.
}