这不能区分b和c;两者都是None,但我希望b成为Some(None).我不依赖于嵌套Option的这种表示形式;可以区分这3种情况的任何解决方案都可以,例如使用自定义枚举的解决方案.解决方案很可能,目前实现此目标的唯一方法是使用自定义反序列化功能.幸运的是,实现它并不难,甚至使其适用于任何领域:fn deserialize_optional_field<'de, T, D>(deserializer: D) -> Result<Option<Option<T>>, D::Error>where D: Deserializer<'de>, T: Deserialize<'de>,{ Ok(Some(Option::deserialize(deserializer)?))}然后将对每个字段进行注释:#[serde(deserialize_with = "deserialize_optional_field")]a: Option<Option<i32>>,您还需要使用#[serde(default)]注释该结构,以便将空字段反序列化为未包装" None.诀窍是将当前值包装在Some周围.序列化依靠另一个技巧:当字段为None时跳过序列化:#[serde(deserialize_with = "deserialize_optional_field")]#[serde(skip_serializing_if = "Option::is_none")]a: Option<Option<i32>>, 游乐场以及完整的示例.输出: Original JSON: {"a": 42, "b": null}> Resource { a: Some(Some(42)), b: Some(None), c: None }< {"a":42,"b":null} I'd like to use Serde to parse some JSON as part of a HTTP PATCH request. Since PATCH requests don't pass the entire object, only the relevant data to update, I need the ability to tell between a value that was not passed, a value that was explicitly set to null, and a value that is present.I have a value object with multiple nullable fields:struct Resource { a: Option<i32>, b: Option<i32>, c: Option<i32>,}If the client submits JSON like this:{"a": 42, "b": null}I'd like to change a to Some(42), b to None, and leave c unchanged.I tried wrapping each field in one more level of Option:#[derive(Debug, Deserialize)]struct ResourcePatch { a: Option<Option<i32>>, b: Option<Option<i32>>, c: Option<Option<i32>>,}playgroundThis does not make a distinction between b and c; both are None but I'd have wanted b to be Some(None).I'm not tied to this representation of nested Options; any solution that can distinguish the 3 cases would be fine, such as one using a custom enum. 解决方案 Quite likely, the only way to achieve that right now is with a custom deserialization function. Fortunately, it is not hard to implement, even to make it work for any kind of field:fn deserialize_optional_field<'de, T, D>(deserializer: D) -> Result<Option<Option<T>>, D::Error>where D: Deserializer<'de>, T: Deserialize<'de>,{ Ok(Some(Option::deserialize(deserializer)?))}Then each field would be annotated as thus:#[serde(deserialize_with = "deserialize_optional_field")]a: Option<Option<i32>>,You also need to annotate the struct with #[serde(default)], so that empty fields are deserialized to an "unwrapped" None. The trick is to wrap present values around Some.Serialization relies on another trick: skipping serialization when the field is None:#[serde(deserialize_with = "deserialize_optional_field")]#[serde(skip_serializing_if = "Option::is_none")]a: Option<Option<i32>>,Playground with the full example. The output:Original JSON: {"a": 42, "b": null}> Resource { a: Some(Some(42)), b: Some(None), c: None }< {"a":42,"b":null} 这篇关于如何区分缺少的反序列化字段和不为null的字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
09-02 11:19