我可以依赖于两个相同结构的序列化是相同的吗?



考虑以下代码:

use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
struct MyStruct {
a: u32,
b: u32
}
#[derive(Serialize, Deserialize)]
#[serde(rename = "MyStruct")]
struct AlsoMyStruct {
a: u32,
b: u32
}

我想知道我是否可以安全地做这样的事情:

let ser = any_encoding::serialize(&MyStruct{a: 33, b: 44}).unwrap();
let deser: AlsoMyStruct = any_encoding::deserialize(&ser).unwrap();

,其中any_encoding为,例如bincode,json,或任何其他serde支持的编码。在我的头脑中,这应该很好地工作:两个结构具有相同的名称(我显式地将AlsoMyStruct重命名为"MyStruct")和完全相同的字段:相同的字段名称,相同的字段类型,相同的字段顺序。

然而,我想知道:这实际上是保证工作吗?或者是否存在一些其他的边缘情况,可能是平台相关的,不可预见的信息,Serde序列化器/反序列化器可能包含在MyStruct/AlsoMyStruct的表示中,从而导致两种表示不兼容?

一般来说,不,您不能期望它工作。原因是服务器和任何反序列化器都不能保证您可以往返数据(源)。这意味着如果你在两个地方使用相同的结构体,你甚至不能期望在所有情况下都能工作。

例如JSON不能往返Option<()>和非自描述的格式,如bincode,不支持无标记的枚举。类型签名中没有强制往返。
以下是反序列化可能失败的一些原因:

  • 使用非自描述格式的skip_serializing_none(serde# 1732)。
  • 任何调用deserialize_any的,例如未标记的,邻接标记的,或内部标记的枚举(serde# 1762)。
  • 反序列化期间的借用,例如&'de str&'de [u8]。如果没有转义序列,serde_json只支持&'de str,不支持&'de [u8]
  • 一些格式不能序列化某些类型,例如,JSON不支持结构体作为映射键和二进制码只支持已知长度的序列(bincode #167)。
  • 一个类型只实现一个特征(Serializer/Deserializer)或实现不匹配,例如,序列化为数字但反序列化为字符串。

也就是说,这个在某些情况下可以工作。结构体应该有相同的名称和相同顺序的字段。Serialize/Deserialize实现的类型也需要支持往返。对于上面的Option<()>,它也依赖于Serializer/Deserializer实现,如果你可以往返它们,即使Serialize/Deserialize实现确实支持它。

许多类型确实尝试支持往返,因为这是最常见的期望。

最新更新