陈天 · 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
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部