Rust 的功能和语法可以通过自定义宏来扩展。 这些宏被赋予名称,并通过一致的语法调用:some_extension!(...)

有两种定义新宏的方式:

  • 实例宏 以高阶的声明方式定义新的语法。
  • 过程宏 以定义操作输入 Token 的函数,实现自定义函数式宏、衍生和属性。

宏调用

语法
宏调用 :
   简单路径 ! 定界Token树

定界Token树 :
      ( Token树* )
   | [ Token树* ]
   | { Token树* }

Token树 :
   Token不包括 定界符号 | 定界Token树

宏调用语句 :
      简单路径 ! ( Token树* ) ;
   | 简单路径 ! [ Token树* ] ;
   | 简单路径 ! { Token树* }

宏调用是在编译期发生,将展开宏,用宏的结果替换调用。 可以在以下语法调用宏:

当宏用作条目或语句时,使用 宏调用语句 语法,当未使用花括号时需要在末尾加上分号。 在宏调用或 macro_rules 定义之前,拒绝 可见性限定符

#![allow(unused)]
fn main() {
// 用作表达式
let x = vec![1,2,3];

// 用作语句
println!("Hello!");

// 用在模式
macro_rules! pat {
    ($i:ident) => (Some($i))
}

if let pat!(x) = Some(1) {
    assert_eq!(x, 1);
}

// 用在类型
macro_rules! Tuple {
    { $A:ty, $B:ty } => { ($A, $B) };
}

type N2 = Tuple!(i32, i32);

// 用在条目
use std::cell::RefCell;
thread_local!(static FOO: RefCell<u32> = RefCell::new(1));

// 用在关联条目
macro_rules! const_maker {
    ($t:ty, $v:tt) => { const CONST: $t = $v; };
}
trait T {
    const_maker!{i32, 7}
}

// 宏中的宏调用。
macro_rules! example {
    () => { println!("Macro call in a macro!") };
}
// 首先展开外部宏 `example` ,然后展开内部宏 `println` 。
example!();
}