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