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

加餐|宏编程(下):用 syn/quote 优雅地构建宏

支持 attributes
优先使用函数而非宏
考虑设计选择
5. 完整实现
4. 使用 quote 生成代码
3. 转换 DeriveInput 到自定义数据结构
2. 定义处理 derive 宏的数据结构
1. 解析 DeriveInput
通过模板转换数据为目标代码
从 TokenStream 抽取数据
使用 syn/quote 重写
生成 TokenStream
替换代码中的 #(...)
任何实现了 Parse trait 的类型都支持 parse() 函数
DeriveInput 结构体
尝试完成 proc-macro-workshop 中的其它例子
宏不应滥用
使用 syn/quote 简化宏编程
支持自定义 attributes
提供 FromField trait
用于解析 attributes
实现步骤
提供 quote!
把代码转换成可操作的数据
Parse trait
特别支持 derive macro
提供丰富的数据结构支持
解析 TokenStream
宏编程是数据结构的转换
分为派生宏、函数宏和属性宏
宏用于生成代码
思考题
小结
darling crate
Builder 派生宏
quote crate
syn crate
宏编程概述
宏编程(下):用 syn/quote 优雅地构建宏

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

你好,我是陈天。
上堂课我们用最原始的方式构建了一个 RawBuilder 派生宏,本质就是从 TokenStream 中抽取需要的数据,然后生成包含目标代码的字符串,最后再把字符串转换成 TokenStream。
说到解析 TokenStream 是个苦力活,那么必然会有人做更好的工具。 syn/quote 这两个库就是 Rust 宏生态下处理 TokenStream 的解析以及代码生成很好用的库。
今天我们就尝试用这个 syn / quote 工具,来构建一个同样的 Builder 派生宏,你可以对比一下两次的具体的实现,感受 syn / quote 构建过程宏的方便之处。

syn crate 简介

先看 syn。syn 是一个对 TokenStream 解析的库,它提供了丰富的数据结构,对语法树中遇到的各种 Rust 语法都有支持
比如一个 Struct 结构,在 TokenStream 中,看到的就是一系列 TokenTree,而通过 syn 解析后,struct 的各种属性以及它的各个字段,都有明确的类型。这样,我们可以很方便地通过模式匹配来选择合适的类型进行对应的处理。
syn 还提供了对 derive macro 的特殊支持——DeriveInput 类型:
pub struct DeriveInput {
pub attrs: Vec<Attribute>,
pub vis: Visibility,
pub ident: Ident,
pub generics: Generics,
pub data: Data,
}
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Rust宏编程的强大工具:syn和quote库 Rust宏编程中,处理TokenStream的解析和代码生成变得更加便捷和优雅,得益于syn和quote库提供的强大工具。syn库通过解析TokenStream,提供了丰富的数据结构,对语法树中的Rust语法有良好支持,特别是对derive macro提供了特殊支持。quote库则提供了quote!宏,能够将代码转换成可操作的数据,保留了代码的所有语义。通过这两个库,可以更轻松地构建宏,提高代码的可读性和可维护性。 在使用syn/quote重写Builder派生宏时,首先通过parse_macro_input!宏将TokenStream解析为DeriveInput结构的数据,然后定义了BuilderContext结构用于处理derive宏的信息。通过From<T> trait的实现,将Field转换为Fd,DeriveInput转换为BuilderContext。这样的实现体现了Rust的优雅和简洁,尤其是在处理Option<T>类型时,使用了一个尚不存在的函数get_option_inner(),以实现对不同类型的处理。 文章还介绍了对attributes的支持,以及如何使用darling库进一步提供对attributes的支持。同时,文章也提醒读者在使用宏时要谨慎,不要过度依赖宏,要将宏编程作为撰写代码最后的手段。 总之,syn和quote库为Rust宏编程提供了强大的工具,使得处理TokenStream的解析和代码生成变得更加便捷和优雅。文章中提供了详细的代码示例和解释,帮助读者更好地理解和应用这些工具。

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

全部留言(3)

  • 最新
  • 精选
  • HiNeNi
    感谢老师加餐!顶顶顶!
    2022-01-26
    1
  • 🐳大海全是水
    可以把宏生成的代码写到代码文件里吗?如果每次都是编译生成,看不见摸不着不好调试,每次生成也比较耗时。
    2023-02-27归属地:广东
  • 小可爱(`へ´*)ノ
    宏用起来还是挺方便的,就是写起来有点复杂。
    2023-01-29归属地:上海
收起评论
显示
设置
留言
3
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部