12.2 过程宏

Rust 的过程宏是一种更强大、更灵活的元编程工具。与基于模式匹配的 macro_rules! 不同,过程宏以 Rust 函数的形式编写,接收输入的代码(以 token 流表示),经过任意逻辑处理后,返回新的 Rust 代码。它们在编译期运行,并能操作完整的抽象语法树(AST),因此适用于需要复杂分析或生成的场景。

过程宏必须定义在独立的 proc-macro crate 中(Cargo.toml 设置 proc-macro = true),且只能导出宏,不能导出普通函数或类型。

Rust 支持三类过程宏:

派生宏(Derive Macros)

派生宏通过 #[derive(...)] 为结构体、枚举等类型自动实现 trait。标准库中的 #[derive(Debug)]#[derive(Clone)] 就是典型例子。自定义派生宏允许你为自己的 trait 自动生成实现。

使用形式:

#[derive(MyTrait)]
struct MyStruct;

在过程宏 crate 中,通过 #[proc_macro_derive(MyTrait)] 定义对应函数。

属性宏(Attribute Macros)

属性宏允许你定义新的 类属性(类似 #[test]#[tokio::main]),可应用于函数、结构体、模块等项。它们能完全替换或包装原始项。

使用形式:

#[my_attribute]
fn my_function() {
    // ...
}

定义时使用 #[proc_macro_attribute],函数接收属性名和被修饰项的 token 流,返回修改后的代码。

例如,#[tokio::main] 实际上是一个属性宏,它将 async fn main() 重写为启动 tokio 运行时的同步函数。

函数式宏(Function-like Macros)

函数式宏在语法上类似函数调用,但由过程宏实现:

my_macro!(arg1, arg2);

macro_rules! 宏不同,它能执行任意 Rust 代码来生成输出,支持更复杂的逻辑(如读取文件、解析 DSL 等)。通过 #[proc_macro] 定义。

基本结构示例

以下是一个简单的派生宏骨架(需在独立的 proc-macro crate 中):

// lib.rs in proc-macro crate
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput};

#[proc_macro_derive(HelloMacro)]
pub fn hello_macro_derive(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    let name = &input.ident;

    let expanded = quote! {
        impl #name {
            pub fn hello_macro() {
                println!("Hello, Macro! My name is {}!", stringify!(#name));
            }
        }
    };

    TokenStream::from(expanded)
}

配合主 crate 使用:

// main.rs
use my_proc_macro::HelloMacro;

#[derive(HelloMacro)]
struct Pancakes;

fn main() {
    Pancakes::hello_macro(); // 输出: Hello, Macro! My name is Pancakes!
}

此例依赖 syn(用于解析 AST)和 quote(用于生成代码),这是编写过程宏的事实标准组合。

优势与代价

  • 优势:功能强大,可实现任意代码生成;能访问完整类型结构;错误信息可定制。
  • 代价:编译速度略慢;调试较复杂;需额外依赖(如 synquote);必须放在独立 crate。

小结

过程宏将 Rust 的元编程能力提升到新高度,使开发者能构建出高度抽象且零成本的 API。无论是自动实现序列化(如 serde)、生成测试桩,还是嵌入领域特定语言,过程宏都是关键工具。理解其三种形式及基本工作流程,是掌握现代 Rust 高级开发的重要一步。后续章节将进一步展示如何编写实用的派生宏。

#Rust 入门教程 分享于 1 周前

内容由 AI 创作和分享,仅供参考