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

如何用Serde在JSON中表示带关联数据的Rust枚举变体?

解决Serde枚举变体的JSON序列化/反序列化问题

你的问题出在枚举变体Particle携带了Particle结构体数据,但你写的JSON只提供了变体名称,没有传递对应的数据。Serde默认对带数据的枚举变体使用外部标签格式,正确的JSON写法应该是:

{
  "kind": {
    "Particle": {
      "mass": 9.10938356e-31
    }
  }
}

为什么这个格式有效?

Serde默认的枚举序列化规则是:对于带关联数据的变体,会把变体名作为键,对应的数据作为值包裹在对象里。所以Kind::Particle(Particle { mass: ... })会被序列化为{"Particle": {"mass": ...}},再嵌套到Spell的kind字段中。

其他可选的枚举序列化格式

如果你觉得默认格式不够直观,可以通过Serde的属性来修改枚举的JSON表示方式:

1. 内部标签格式

在枚举上添加#[serde(tag = "type")]属性,把变体名放到内部的type字段里,数据作为同级字段:

#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "type")]
enum Kind {
    Particle(Particle)
}

对应的JSON格式:

{
  "kind": {
    "type": "Particle",
    "mass": 9.10938356e-31
  }
}

2. 无标签格式

使用#[serde(untagged)]属性,让Serde自动推断变体,适合变体结构差异明显的场景:

#[derive(Debug, Serialize, Deserialize)]
#[serde(untagged)]
enum Kind {
    Particle(Particle)
}

对应的JSON格式(直接把结构体数据作为kind的值):

{
  "kind": {
    "mass": 9.10938356e-31
  }
}

注意:如果枚举有多个变体且结构相似,无标签格式可能导致反序列化歧义,需谨慎使用。

3. 相邻标签格式

添加#[serde(tag = "type", content = "data")],把变体名和数据分在两个同级字段:

#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "type", content = "data")]
enum Kind {
    Particle(Particle)
}

对应的JSON格式:

{
  "kind": {
    "type": "Particle",
    "data": {
      "mass": 9.10938356e-31
    }
  }
}

这些格式可以根据你的API设计需求选择,默认的外部标签格式是最明确、不易出错的选项。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 22:23:13