宏
Rust 的功能和语法可以通过称为宏的自定义定义进行扩展。它们被赋予名称,并通过一致的语法进行调用:some_extension!(...)。
有两种方法可以定义新的宏
- 按示例宏(Macros by Example)以更高级别的声明方式定义新语法。
- 过程宏(Procedural Macros)使用操作输入 token 的函数定义类似函数的宏、自定义 derive 和自定义属性。
宏调用
语法
MacroInvocation :
SimplePath!DelimTokenTreeDelimTokenTree :
(TokenTree*)
|[TokenTree*]
|{TokenTree*}TokenTree :
Token除了 分隔符 | DelimTokenTreeMacroInvocationSemi :
SimplePath!(TokenTree*);
| SimplePath![TokenTree*];
| SimplePath!{TokenTree*}
宏调用在编译时展开宏,并将调用替换为宏的结果。宏可以在以下情况中被调用
macro_rules转录器
当用作项或语句时,使用 MacroInvocationSemi 形式,如果不是用花括号,末尾需要分号。可见性限定符绝不允许出现在宏调用或 macro_rules 定义之前。
#![allow(unused)] fn main() { // Used as an expression. let x = vec![1,2,3]; // Used as a statement. println!("Hello!"); // Used in a pattern. macro_rules! pat { ($i:ident) => (Some($i)) } if let pat!(x) = Some(1) { assert_eq!(x, 1); } // Used in a type. macro_rules! Tuple { { $A:ty, $B:ty } => { ($A, $B) }; } type N2 = Tuple!(i32, i32); // Used as an item. use std::cell::RefCell; thread_local!(static FOO: RefCell<u32> = RefCell::new(1)); // Used as an associated item. macro_rules! const_maker { ($t:ty, $v:tt) => { const CONST: $t = $v; }; } trait T { const_maker!{i32, 7} } // Macro calls within macros. macro_rules! example { () => { println!("Macro call in a macro!") }; } // Outer macro `example` is expanded, then inner macro `println` is expanded. example!(); }