使用 macro_rules 编写生产 Rust 宏!

💡 原文中文,约2300字,阅读约需6分钟。
📝

内容提要

本指南介绍了使用macro_rules编写Rust宏的方法,包括声明式宏、模式匹配和源代码输出。还介绍了assert_eq宏的使用和参数模式,以及宏卫生特性和完全限定的模块路径的重要性。

🔎

延伸解读

声明式宏与程序宏的分工

文章指出Rust宏主要分为声明式宏和程序宏。声明式宏使用macro_rules!定义,通过模式匹配处理标记并生成代码,是Rust宏的主体;程序宏则涉及对标记流的编程操作,属于宏家族的其他部分。理解这一区分有助于在编写宏时选择合适的方式。

assert_eq!的双规则设计

assert_eq!支持两种参数模式:一是比较两个表达式,二是额外接受格式字符串和参数。因此其定义包含两条规则,分别匹配这两种情况。两条规则生成的代码结构相似,都先对左右表达式求值并保存引用,避免重复求值,然后进行相等性检查,失败时触发panic。

宏卫生与完全限定路径

宏卫生特性确保宏内部定义的变量(如kind)不会与调用处同名变量冲突。同时,使用$crate::panicking::AssertKind::Eq这样的完全限定路径,可以避免要求用户导入实现细节,因为#[macro_export]导出的宏在使用时作用域中不保证存在这些路径。

❓

Q&A

Rust中的宏是什么?

Rust中的宏是通过宏规则进行模式匹配并输出源代码的工具,主要分为声明式宏和程序宏。

如何使用assert_eq宏进行比较?

assert_eq宏支持两种参数模式:一种比较两个表达式,另一种接受格式字符串及其参数进行插值。

什么是宏卫生特性?

宏卫生特性确保宏内部变量不会与外部变量冲突,从而避免命名冲突问题。

为什么要使用完全限定的模块路径?

使用完全限定的模块路径可以避免用户在使用宏时需要导入实现细节,从而简化使用过程。

assert_eq宏的定义包含哪些规则?

assert_eq宏的定义包含两条规则,分别处理比较两个表达式和接受格式字符串及其参数的情况。

TokenTree在Rust宏中有什么作用?

TokenTree可以是单个标记或嵌套标记的组合,用于在宏中处理不同类型的输入。

🏷️

标签

➡️

继续阅读