考虑以下代码:
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"
)和完全相同的字段:相同的字段名称,相同的字段类型,相同的字段顺序。
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
实现确实支持它。
许多类型确实尝试支持往返,因为这是最常见的期望。