什么是宏
概念名称: 宏是"代码的代码",在编译时生成代码,减少重复。
语法结构:
┌──────────────────────────────────────┐
│ macro_rules! 宏名 { │
│ (模式) => { 展开代码 }; │
│ } │
│ │
│ 调用:宏名!(参数) │
│ │
│ 声明式宏:macro_rules! │
│ 过程宏:#[derive], #[attr], func! │
└──────────────────────────────────────┘最简示例
rust
▶ Runmacro_rules! say_hello {
() => {
println!("Hello from macro!");
};
}
fn main() {
say_hello!();
}宏 vs 函数
┌─────────────────────────────────────────────────────┐
│ 宏是什么 │
├─────────────────────────────────────────────────────┤
│ │
│ 宏 = 代码的代码 │
│ │
│ 宏 vs 函数: │
│ ┌─────────────┬─────────────┬─────────────┐ │
│ │ │ 函数 │ 宏 │ │
│ ├─────────────┼─────────────┼─────────────┤ │
│ │ 展开时机 │ 运行时 │ 编译时 │ │
│ │ 参数类型 │ 固定 │ 灵活 │ │
│ │ 调用开销 │ 有 │ 无 │ │
│ │ 调试 │ 容易 │ 较难 │ │
│ │ 编译速度 │ 快 │ 慢 │ │
│ └─────────────┴─────────────┴─────────────┘ │
│ │
└─────────────────────────────────────────────────────┘为什么用它?
rust
▶ Run// 没有宏:重复代码,难以维护
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);宏的类型
Rust 有两种宏:
1. 声明式宏 (macro_rules!)
• 类似模式匹配
• 定义在 crate 中
• 本章重点
2. 过程宏 (Proc Macro)
• 操作 AST
• 需要单独的 crate
• 包括:#[derive], #[attribute], function!关键代码说明:
| 代码 | 含义 | 为什么这样写 |
|---|---|---|
macro_rules! | 声明宏关键字 | 定义模式匹配规则 |
($val:expr) | 参数模式 | expr 匹配任意表达式 |
stringify!($val) | 转为字符串 | 编译时将代码转为字符串字面量 |
宏名!() | 调用宏 | ! 表示这是宏调用 |