You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Rust的macro_rules!宏中添加Serde序列化与反序列化支持

支持Serde序列化的结构体字段计数宏修改方案

要让宏支持接收#[derive(Deserialize, Serialize)]这类属性,只需在宏规则中添加对元属性的匹配逻辑,将属性直接应用到生成的结构体上即可。以下是修改后的完整实现:

use serde::{Deserialize, Serialize}; // 需要在Cargo.toml中添加serde依赖并启用derive特性

macro_rules! generate {
    // 新增支持可选属性的规则,匹配任意数量的#[...]属性
    ($(#[$attr:meta])* $name:ident {$($field:ident : $t:ty),+}) => {
        // 将匹配到的属性直接应用到结构体定义上
        $(#[$attr])*
        struct $name { $($field: $t),+ }
        impl $name {
            fn field_count(&self) -> usize {
                generate!(@count $($field),+)
            }
        }
    };
    // 保留原有无属性规则,保证向后兼容
    ($name:ident {$($field:ident : $t:ty),+}) => {
        generate!() $name {$($field: $t),+}
    };
    // 字段计数的递归规则,保持原有逻辑不变
    (@count $t1:tt, $($t:tt),+) => { 1 + generate!(@count $($t),+) };
    (@count $t:tt) => { 1 };
}

// 带Serde derive属性的宏调用示例
generate! {
    #[derive(Debug, Serialize, Deserialize)]
    test1 { num: i32, s: Option<String> }
}

// 原有无属性的宏调用仍可正常使用
generate! { test2 { num: i32, s: String }}

fn main() {
    let s1 = test1 { num: 0, s: None };
    println!("test1字段数: {}", s1.field_count());
    // 测试序列化功能
    let json = serde_json::to_string(&s1).unwrap();
    println!("test1序列化结果: {}", json);
    
    let s2 = test2 { num: 0, s: String::new() };
    println!("test2字段数: {}", s2.field_count());
}

关键修改说明

  • 新增的宏规则通过$(#[$attr:meta])*语法匹配任意数量的元属性(如#[derive(...)]),并将这些属性原样输出到结构体定义上方,确保派生特性正常生效。
  • 保留原有的无属性调用规则,旧代码无需修改即可继续运行。
  • 字段计数的递归逻辑完全复用原有实现,不影响核心功能。

Cargo.toml依赖配置

需要添加serde及serde_json的依赖:

[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

内容的提问来源于stack exchange,提问作者bluestacks454

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 02:01:14