陈天 · Rust 编程第一课
陈天
Tubi TV 研发副总裁
23196 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 65 讲
基础篇 (21讲)
陈天 · Rust 编程第一课
15
15
1.0x
00:00/00:00
登录|注册

加餐|宏编程(上):用最“笨”的方式撰写宏

build() 方法构造结构体实例
链式调用设置字段
为结构体生成 builder 方法
生成 hello() 函数
打印输入的 TokenStream
从元素和数量创建 Vec
处理逗号分隔的表达式
创建空的 Vec
示例: Builder 宏
生成代码的宏
示例: query! 宏
输入和输出都是 TokenStream
比声明宏复杂
示例: my_vec! 宏
基于模式匹配
使用 macro_rules!
减少手工编码的体力活
自动化重复性代码生成
学习其他语言宏编程的基础
理解 token stream / token tree 概念
转换 protobuf 定义到 Rust struct/enum
使用 generate! 宏根据 openapi v3 spec 生成 Rust 类型
生成 CommandBuilder 结构和方法
从 TokenStream 中提取结构体和字段信息
使用 askama 处理模板
创建 RawBuilder 派生宏
将字符串转换回 TokenStream
生成目标代码的字符串
从 TokenStream 中提取数据
派生宏
过程宏
声明宏
数据结构到数据结构的转换
将一棵语法树转换成另一棵语法树
Rust 宏编程的意义
思考题
实践
宏编程的关键点
Rust 中的宏
宏的本质
Rust 宏编程

该思维导图由 AI 生成,仅供参考

你好,我是陈天。
学过上一讲,相信你现在应该理解为什么在课程的第 6 讲我们说,宏的本质其实很简单,抛开 quote/unquote,宏编程主要的工作就是把一棵语法树转换成另一颗语法树,而这个转换的过程深入下去,不过就是数据结构到数据结构的转换。
那在 Rust 里宏到底是如何做到转换的呢?
接下来,我们就一起尝试构建声明宏和过程宏。希望你能从自己撰写的过程中,感受构建宏的过程中做数据转换的思路和方法,掌握了这个方法,你可以应对几乎所有和宏编程有关的问题。

如何构建声明宏

首先看声明宏是如何创建的。
我们 cargo new macros --lib 创建一个新的项目,然后在新生成的项目下,创建 examples 目录,添加 examples/rule.rs(代码):
#[macro_export]
macro_rules! my_vec {
// 没带任何参数的 my_vec,我们创建一个空的 vec
() => {
std::vec::Vec::new()
};
// 处理 my_vec![1, 2, 3, 4]
($($el:expr),*) => ({
let mut v = std::vec::Vec::new();
$(v.push($el);)*
v
});
// 处理 my_vec![0; 10]
($el:expr; $n:expr) => {
std::vec::from_elem($el, $n)
}
}
fn main() {
let mut v = my_vec![];
v.push(1);
// 调用时可以使用 [], (), {}
let _v = my_vec!(1, 2, 3, 4);
let _v = my_vec![1, 2, 3, 4];
let v = my_vec! {1, 2, 3, 4};
println!("{:?}", v);
println!("{:?}", v);
//
let v = my_vec![1; 10];
println!("{:?}", v);
}
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Rust宏编程是一项强大的技术,本文深入介绍了它的基本原理和使用方法。文章详细讨论了声明宏和过程宏两种类型,以及如何利用模式匹配实现参数的捕获和展开,从而简化重复代码的处理。特别强调了过程宏中最有意义的一类——派生宏,并通过示例代码展示了如何构建过程宏,以及TokenStream和TokenTree的基本结构。此外,文章还提供了一个思考题,引导读者通过宏来简化从第三方schema生成Rust数据结构的操作。总的来说,本文内容深入浅出,对于想要了解Rust宏编程的读者来说,是一份很好的参考资料。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《陈天 · Rust 编程第一课》
,新⼈⾸单¥68
立即购买
登录 后留言

全部留言(6)

  • 最新
  • 精选
  • pedro
    值!
    2022-01-25
    3
  • Geek_4df987
    如果传入用冒号分隔的两个表达式 错别字:应该是用 “分号” 分隔
    2023-09-28归属地:北京
  • Geek_4df987
    另一颗语法树 错别字
    2023-09-28归属地:北京
  • 孔祥旭
    您好, 我运行程序之后, query!(xxxxx)并没有输出任何信息, 这是怎么一回事, 我在宏的上面和下面定义了println("1"), 均有输出
    2023-06-12归属地:广东
    2
  • 记事本
    陈老师,无法识别use proc_macro::{TokenStream} unresolved import 克隆你仓库的代码都一样
    2022-03-05
  • 记事本
    清楚
    2022-03-05
收起评论
显示
设置
留言
6
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部