← [ BACK_TO_NOTES ]

Rust 宏

声明宏与过程宏的定位:编译期代码生成、derive、适用边界与可读性权衡。

#concept #growing #dev #rust

[!info] related notes

Rust 宏

这个概念为什么出现

需要在编译期生成样板:测试矩阵、DSL、derive 实现。
声明宏按 token 模式匹配展开;过程宏接收和返回 TokenStream,可自行解析为语法树,不能假定输入已经完成类型检查。

[!abstract] 一句话理解 macro_rules! 做声明宏匹配;过程宏(derive/attribute/function-like)用 Rust 写编译期插件;优先函数/泛型,宏用于真需要语法层扩展时。

最小可运行示例

场景:快速生成命名日志宏

// 业务意图:统一前缀日志。
// 教学点:macro_rules 基础。

macro_rules! audit {
    ($($arg:tt)*) => {{
        println!("[audit] {}", format_args!($($arg)*));
    }};
}

fn main() {
    let user = 7;
    audit!("login user={user}");
}

建议运行:cargo run

期望:[audit] login user=7

结合场景再看三个关注点

  1. 宏在调用点展开
  2. macro_rules 的卫生性有边界;跨 crate 导出宏引用自身项目时常需 $crate,过程宏输出也要避免名称冲突
  3. 复杂逻辑优先函数

核心概念与准确模型

种类例子
声明宏println!、vec!、自写 macro_rules
derive 宏#[derive(Debug, Serialize)]
属性宏#[tokio::main]
函数式过程宏sqlx::query!

设计动机

  • 消除重复
  • 领域语法
  • 编译期计算/校验

边界与误区

  • 错误信息难读
  • 过度 DSL
  • 编译时间上升

[!warning] 常见误区:用宏代替清晰 API 先泛型/函数,不够再宏。

工程实践

  1. 小 macro_rules 可接受
  2. 自定义过程宏通常放在设置 [lib] proc-macro = true 的独立 crate,名称不要求 *_derive
  3. 文档展示展开意图
  4. 测试宏展开场景

本节总结

  • 宏 = 编译期代码生成
  • 声明宏入门,过程宏生态重
  • 克制使用

自测题

  1. println! 为何是宏不是函数?
  2. derive 解决什么样板?
参考答案
  1. 可变参数格式字符串需编译期处理。
  2. 自动生成 trait 实现(Debug/Clone/Serde…)。

延伸阅读与资料来源

资料类型支撑内容
The Book — Macros官方书宏
The Little Book of Rust Macros社区深入声明宏
创建于 2026/7/15 更新于 2026/10/7
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本