第3章 宏

宏 — The Rust Reference

译文 · 基于 The Rust Reference

原文链接: https://doc.rust-lang.org/reference/macros.html

r[macro]

宏

r[macro.intro] Rust 的功能与语法可以通过称为宏的自定义定义来扩展。它们被赋予名称,并通过一致的语法调用:some_extension!(...)。

定义新宏有两种方式:

  • 示例宏 以更高层、声明式的方式定义新语法。
  • 过程宏 使用对输入 token 进行操作的函数,定义函数式宏、自定义 derive 以及自定义属性。

r[macro.invocation]

宏调用

r[macro.invocation.syntax]

MacroInvocation ->
    SimplePath `!` DelimTokenTree

DelimTokenTree ->
      `(` TokenTree* `)`
    | `[` TokenTree* `]`
    | `{` TokenTree* `}`

TokenTree ->
    Token _except [delimiters][lex.token.delim]_ | DelimTokenTree

MacroInvocationSemi ->
      SimplePath `!` `(` TokenTree* `)` `;`
    | SimplePath `!` `[` TokenTree* `]` `;`
    | SimplePath `!` `{` TokenTree* `}`

r[macro.invocation.intro] 宏调用在编译时展开宏,并用宏的结果替换该调用。宏可在下列情形中被调用:

r[macro.invocation.expr]

r[macro.invocation.pattern]

r[macro.invocation.type]

r[macro.invocation.item]

r[macro.invocation.nested]

r[macro.invocation.extern]

r[macro.invocation.item-statement] 当用作项或语句时,使用 [MacroInvocationSemi] 形式:在不使用花括号时,末尾需要分号。在宏调用或 macro_rules 定义之前从不允许 可见性限定符。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// 用作表达式。
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!();

r[macro.invocation.name-resolution]

宏调用可通过两种作用域解析:


01-示例宏

示例宏 — The Rust Reference

02-过程宏

过程宏 — The Rust Reference

最后修改 August 21, 2026: 更新 (76fc81a2e)