Skip to content

什么是宏

概念名称: 宏是"代码的代码",在编译时生成代码,减少重复。

语法结构:
┌──────────────────────────────────────┐
│  macro_rules! 宏名 {                  │
│      (模式) => { 展开代码 };          │
│  }                                    │
│                                       │
│  调用:宏名!(参数)                    │
│                                       │
│  声明式宏:macro_rules!              │
│  过程宏:#[derive], #[attr], func!   │
└──────────────────────────────────────┘

最简示例

rust
macro_rules! say_hello {
    () => {
        println!("Hello from macro!");
    };
}

fn main() {
    say_hello!();
}
▶ Run

宏 vs 函数

┌─────────────────────────────────────────────────────┐
│              宏是什么                                │
├─────────────────────────────────────────────────────┤
│                                                     │
│  宏 = 代码的代码                                     │
│                                                     │
│  宏 vs 函数:                                        │
│  ┌─────────────┬─────────────┬─────────────┐       │
│  │             │ 函数        │ 宏          │       │
│  ├─────────────┼─────────────┼─────────────┤       │
│  │ 展开时机    │ 运行时      │ 编译时      │       │
│  │ 参数类型    │ 固定        │ 灵活        │       │
│  │ 调用开销    │ 有          │ 无          │       │
│  │ 调试        │ 容易        │ 较难        │       │
│  │ 编译速度    │ 快          │ 慢          │       │
│  └─────────────┴─────────────┴─────────────┘       │
│                                                     │
└─────────────────────────────────────────────────────┘

为什么用它?

rust
// 没有宏:重复代码,难以维护
fn print_i32(x: i32) { println!("i32: {}", x); }
fn print_str(x: &str) { println!("str: {}", x); }
fn print_bool(x: bool) { println!("bool: {}", x); }

// 有宏:一套代码,多种类型
macro_rules! print_val {
    ($val:expr) => {
        println!("{}: {:?}", stringify!($val), $val);
    };
}

print_val!(42);
print_val!("hello");
print_val!(true);
▶ Run

宏的类型

Rust 有两种宏:

1. 声明式宏 (macro_rules!)
   • 类似模式匹配
   • 定义在 crate 中
   • 本章重点

2. 过程宏 (Proc Macro)
   • 操作 AST
   • 需要单独的 crate
   • 包括:#[derive], #[attribute], function!

关键代码说明:

代码含义为什么这样写
macro_rules!声明宏关键字定义模式匹配规则
($val:expr)参数模式expr 匹配任意表达式
stringify!($val)转为字符串编译时将代码转为字符串字面量
宏名!()调用宏! 表示这是宏调用