59·高级

过程宏 derive 宏

过程宏 derive 宏

学习目标

  1. 理解过程宏的三种类型
  2. 理解 derive 宏的原理
  3. 了解 syn/quote 生态

核心概念

过程宏类型

1. 自定义 derive 宏: #[derive(MyTrait)]
2. 属性宏: #[my_attribute]
3. 函数式宏: my_macro!(...)

derive 宏的工作原理

// 输入:TokenStream(Rust 代码的 token 流)
// 输出:TokenStream(要追加的代码)

// #[derive(HelloMacro)]
// struct Pancakes;

// 过程宏生成:
// impl HelloMacro for Pancakes {
//     fn hello_macro() {
//         println!("Hello, Macro! My name is Pancakes");
//     }
// }

创建 derive 宏

# Cargo.toml
[lib]
proc-macro = true

[dependencies]
syn = "2"
quote = "1"
proc-macro2 = "1"
// src/lib.rs
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 HelloMacro for #name {
            fn hello_macro() {
                println!("Hello, Macro! My name is {}", stringify!(#name));
            }
        }
    };

    TokenStream::from(expanded)
}

属性宏

#[proc_macro_attribute]
pub fn route(attr: TokenStream, item: TokenStream) -> TokenStream {
    // attr: 宏属性参数
    // item: 被标注的函数
    item
}

函数式宏

#[proc_macro]
pub fn sql(input: TokenStream) -> TokenStream {
    // 解析 SQL 字符串并生成代码
    input
}

常用 derive 宏

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Serialize, Deserialize)]  // serde
#[derive(Error)]                     // thiserror

小结

类型语法用途
derive 宏#[derive(MyTrait)]自动实现 trait
属性宏#[my_attr]标注修改函数/结构体
函数式宏my_macro!(...)自定义语法
syn解析 TokenStream将代码转为 AST
quote生成 TokenStream将 AST 转回代码

练习编辑器

rust
Loading...