当前位置:嗨网首页>书籍在线阅读

13-过程宏

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

9.11 过程宏

当代码生成逻辑变得复杂时,声明式宏可能会变得冗长、乏味,因为你需要使用自己的DSL编写逻辑来操作标记。有比使用macro_rules!宏更好、更灵活的方法。对于复杂问题,你可以使用过程宏,因为它们更适合编写优秀的程序,它们适用于需要完全控制代码生成的情况。

过程宏实现为函数,这些函数接收宏输入作为标记流(TokenStream)类型,并在编译时进行相关转换后,将生成的代码作为标记流返回。要将函数标记为过程宏,我们需要使用#[proc_macro]属性对其进行注释。编写本书时,过程宏包含3种形式,按照它们的调用方式可以进行如下分类。

  • 类函数过程宏:它们在函数上使用#[proc_macro]属性。lazy_static程序库中的lazy_static!宏就采用了类函数过程宏。
  • 类过程宏:它们在函数上使用#[proc_macro_attribute]属性。wasm-bindgen程序库中的#[wasm-bindgen]属性就采用类过程宏。
  • 派生过程宏:它们使用#[proc_macro_derive]属性。这些是大多数Rust软件包中最常见的宏,例如serde程序库。由于引入了它们的RFC的名称,它们有时也被称为派生宏或宏1.1。

在编写本书时,过程宏API对标记流的处理功能非常有限,因此我们需要使用第三方的软件包,例如syn和quote,以便将输入解析为Rust代码数据结构,然后可以根据你的代码生成需要进行分析。此外,需要将过程宏创建为具有proc-macro = true属性的单独程序库,该属性在Cargo.toml文件中指定。为了使用宏,我们可以通过在Cargo.toml中的依赖项下指定宏,从而像引用其他软件包那样引用宏,并使用use语句导入宏。

在这3种形式中,派生宏是最广泛采用的过程宏形式。接下来我们将深入探讨它们。