rust - 如何在`serde::ser::Serialize`的impl中跳过序列化?
问题描述
我想完全基于自定义实现中的某些值跳过序列化Serialize
impl Serialize for MyType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match &self.value {
Action::Serialize => //serialize.serialize_struct( etc...
Action::NoSerialize => Ok(()) // <= Error. How do I return Ok and skip serialization ?
}
}
}
错误消息读取
mismatched types
expected associated type `<S as mystuff::_::_serde::Serializer>::Ok`
found unit type `()`rustcE0308
mod.rs(160, 22): consider constraining the associated type `<S as mystuff::_::_serde::Serializer>::Ok` to `()`: `<Ok = ()>`
但我不知道如何指定建议的约束<Ok = ()>
解决方案
这将取决于序列化程序。一些序列化程序(例如 Bincode)会跳过单位值,所以你可以只使用Serializer::serialize_unit()
. 然而,其他人,如serde_json
,将给出单位值,例如null
。
问题是,在某些情况下,序列化程序需要一个值。例如,如果您要序列化为 Json 映射(对象字面量),则没有值的键是没有意义的,但是您甚至在检查值之前就已经序列化了键。
因此,要一般地跳过值,您需要自定义包含该值的结构或集合的序列化,以确定要执行的正确操作。在某些情况下,这可能意味着为“父”类型编写自定义序列化,以使其了解需要跳过的内容。其他时候,您可以使用serde
属性来自定义它:
#[derive(Serialize)]
pub struct Parent {
#[serde(skip_serializing_if = "MyType::no_serialize")]
pub my_value: MyType,
}
impl MyType {
fn no_serialize(&self) -> bool {
matches!(self, Action::NoSerialize)
}
}
但我不知道如何指定建议的约束
<Ok = ()
>
在这种情况下,这个建议是一个红鲱鱼。这是您正在使用Ok
的关联类型。Serializer
这不是您可以更改的东西,将其更改为()
将意味着创建一个序列化格式,该格式对于所有值都是空的。
推荐阅读
- javascript - 如何验证来自 word 文件的文件图像被重命名为图像文件
- arrays - 检查 JSON 是 Groovy 脚本中的结构还是数组
- c# - 带有实体框架的 ASP.NET MVC 模型中的虚拟集合未显示在详细信息视图中
- cassandra - 为什么 DSBulk Load 可能会在没有任何错误的情况下停止操作?
- python - 如何将数据框添加到 django 模型(sqlite3)?
- vim - 将 Netrw 的浏览目录更改为 Vim 的当前目录?
- angular - 如何在 Angular 应用程序的量角器测试中使用 NgZone
- controller - 更新文件路径错误在 null 上调用成员函数 getClientOriginalName() 并且文件必须是以下类型的文件:pdf、doc、docx
- java - 以编程方式下载和安装 apk android 10 11 的问题
- sharepoint - SharePoint 列表中的 URL 重定向