在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
相关产品推荐
相关产品推荐

