片段说明符种类的模式
在 $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.
}