使用serde_json序列化默认枚举变体时输出null问题
问题分析与解决:可选枚举字段序列化默认值为null的问题
核心问题出在**Option<Version>的默认值是None**:你给version字段加了#[serde(default)],但这个属性只会把未初始化的Option字段设为None,而None序列化后就是null——这和你定义的Version枚举默认值无关,因为Option的默认值优先级高于内部类型的默认值。
要实现你期望的效果,需要让version字段的默认值是Some(Version::PlayV2),而非None,这里有两种常用方案:
方案一:用serde(default = "...")指定自定义默认值
给version字段指定一个返回Some(Version::default())的辅助函数,替代默认的None:
use serde::{Deserialize, Serialize}; use serde_json; #[derive(Debug, Default, Clone, Serialize, Deserialize)] struct Foo { pub text: String, // 指定自定义默认值函数 #[serde(default = "default_version")] pub version: Option<Version>, } // 定义返回Some(默认枚举值)的辅助函数 fn default_version() -> Option<Version> { Some(Version::default()) } #[derive(Debug, Clone, Deserialize, Serialize, Default)] pub enum Version { #[serde(rename = "PlayV1.0")] PlayV1, #[serde(rename = "PlayV2.0")] #[default] PlayV2, } fn main() { let req = Foo { text: "Hello, world!".to_string(), ..Default::default() }; let json = serde_json::to_string(&req).unwrap(); println!("{}", json); // 输出:{"text":"Hello, world!","version":"PlayV2.0"} }
方案二:去掉Option类型(如果业务允许)
如果你的业务逻辑中version字段不需要为None,直接把字段类型改成Version,#[serde(default)]会自动使用Version的默认值:
use serde::{Deserialize, Serialize}; use serde_json; #[derive(Debug, Default, Clone, Serialize, Deserialize)] struct Foo { pub text: String, #[serde(default)] pub version: Version, // 去掉Option } #[derive(Debug, Clone, Deserialize, Serialize, Default)] pub enum Version { #[serde(rename = "PlayV1.0")] PlayV1, #[serde(rename = "PlayV2.0")] #[default] PlayV2, } fn main() { let req = Foo { text: "Hello, world!".to_string(), ..Default::default() }; let json = serde_json::to_string(&req).unwrap(); println!("{}", json); // 输出:{"text":"Hello, world!","version":"PlayV2.0"} }
这两种方案都能达到你想要的序列化效果,具体选哪种取决于你的业务是否需要version字段支持None的情况。
内容的提问来源于stack exchange,提问作者milosgajdos
相关产品推荐
相关产品推荐

