宏
Rust 的功能和语法可以通过称为宏(Macro)的自定义定义来扩展。它们被赋予名称,并通过一致的语法调用:some_extension!(...)。
有两种定义新宏的方式:
宏调用
Syntax
MacroInvocation →
SimplePath ! DelimTokenTree
DelimTokenTree →
( TokenTree* )
| [ TokenTree* ]
| { TokenTree* }
TokenTree →
Tokenexcept delimiters | DelimTokenTree
MacroInvocationSemi →
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!();
}
宏调用可以通过两种作用域进行解析:
- 文本作用域
- 基于路径的作用域