第9章 宏:法条批量生成


第 9 章 · 宏:法条批量生成

本章要回答的两个问题:为什么 println! 带感叹号、为什么格式串错误能编译期报错?声明宏与过程宏各自怎么生成代码?

为什么要有这一章

从第 1 章的 println! 到第 4 章的 derive(Debug),宏一直在场:它接收标记流、产出代码,让"编译期写代码"成为语言能力而非外部生成器。函数接收值,宏接收语法——这一步之差使格式检查、派生实现、DSL 构造都成为可能。本章拆开这台"法条批量生成器"。

读完能解决什么

  • 读懂常见声明宏的规则语法,能写简单实用宏;
  • 分清三类过程宏(派生、属性、函数式)的用途与形态;
  • 理解 derive 背后发生了什么,不再把它当魔法。

各节怎么分工

节 回答哪个问题 关键产出
9.1 声明宏 规则怎么写、怎么展开 自制 vec 式宏、重复模式语法
9.2 过程宏 派生与属性宏怎么工作 三类过程宏对照、派生示例

先决条件

  • 第 4 章结构体(派生的对象)、第 7 章 crate 概念(过程宏需要独立 crate)。

往下走到哪

宏是 Rust 生态扩展性的支柱:serde、错误派生、测试框架全都建在它上面。读完再看这些库的"魔法",看到的只是规则。

本章判例速查

报错/现象 案情 修法方向
no rules expected 模式没覆盖到该输入 补分支或调整说明符
recursion limit 递归展开过深 加 recursion_limit 或改迭代式
macro expansion ignores token 说明符选错 按语法单元类别换说明符
过程宏 panic 生成代码不合法 cargo expand 检查产物

宏的纪律边界

宏的廉价性是双刃:能写不代表该写。三条经验红线——宏展开后控制流不可见(调试断点失踪);三个以上片段说明符的组合应重审是否该用函数+泛型;团队公共宏必须有文档说明展开形态。判断口诀:重复的语法结构用宏,重复的逻辑用函数。语法层面的重复(样板 impl、注册清单)才是宏的法定辖区。

与下一章的衔接

宏在编译期生成代码,本章结束意味着"安全区内的全部装备"已经发齐。第 10 章走出安全区:Unsafe、FFI 与异步。前者的 raw 指针、次者的 extern 块、后者的状态机变换,处处要靠前面九章的纪律兜底——终审庭审的不只是新知识,更是旧纪律。

宏章自查

三个问题检验本章掌握度:给定一段宏调用,能否指出每个片段落入哪个说明符;能否解释宏卫生为什么防止了变量撞名;能否说出 derive 宏、属性宏、函数式过程宏各自的挂载点。三问之外加一条实践线:把第 8 章 worker 池的样板用 macro_rules 包一层,做完这个练习,"何时该用宏"的手感就替代了记忆。

三道自测题

一问:声明宏为什么不能读类型信息?答:展开发生在类型检查之前,宏只见语法树。二问:$(...),* 与 $(...),+ 的差别?答:星号允许零次,加号至少一次。三问:过程宏 crate 为什么必须独立?答:它编译成特殊动态库供编译器加载,与普通库的产物形态不同,混装无法工作。三题收口,宏章的判例就齐了。

宏与前章的合议

宏章放在第九章的深意此刻可以点破:声明宏的卫生性建立在第 3 章的产权模型上(宏不偷变量,本质是标识符的属地规则);过程宏的 derive 在第 5 章、测试样板在第 7 章、worker 池在第 8 章都已预演过用途。学会宏的标志不是会写匹配规则,而是能在设计阶段识别"这段样板该宏化了"——识别力来自前八章的判例积累,这正是课程排序的用意。至此,安全区内的全部装备已经发齐,终审庭只剩三件事:越权、跨境、异步。

收束判词

宏章的考核标准最终一条:在 code review 里看到一段宏,能说出它的展开形态与 hygiene 边界。达标的检验动作是 cargo expand——把自己的三个宏各展开一次,逐行读产物。读完的普遍感受是"原来这么朴素",而这种朴素正是宏设计得当的标志:好的宏展开成平凡代码,坏的宏展开成谜题。

作者与出处
原作者:灏天文库
来源:平台策划编纂
整理人: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U