考虑以下代码:
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
}
Run Code Online (Sandbox Code Playgroud)
我想知道我是否可以安全地做类似的事情:
let ser = any_encoding::serialize(&MyStruct{a: 33, b: 44}).unwrap();
let deser: AlsoMyStruct = any_encoding::deserialize(&ser).unwrap();
Run Code Online (Sandbox Code Playgroud)
其中any_encoding是,例如bincode、json或任何其他 Serde 支持的编码。在我看来,这应该很好地工作:两个结构具有相同的名称(我明确重命名AlsoMyStruct为"MyStruct")和完全相同的字段:相同的字段名称、相同的字段类型、相同的字段顺序。
但是,我想知道:这真的能保证有效吗?MyStruct或者 Serde 序列化器/反序列化器是否可能在/的表示中包含一些其他的、极端情况的、可能与平台相关的、不可预见的信息,AlsoMyStruct这些信息可能会导致两种表示不兼容?
一般来说,不,你不能指望这能起作用。原因是 Serde 和任何反序列化器都不能保证您可以往返数据(源)。这意味着如果您在两个地方使用相同的结构,您甚至不能期望它在所有情况下都有效。
例如,JSON 无法往返Option<()>,并且非自描述格式(如 bincode)不支持未标记的枚举。类型签名中没有任何内容强制往返。
以下是反序列化可能失败的一些原因:
skip_serializing_none非自描述格式(serde #1732)。deserialize_any,例如未标记的、相邻标记的或内部标记的枚举(serde #1762)。&'de str或&'de [u8]。serde_json仅&'de str在没有转义序列的情况下支持,并且从不支持&'de [u8].Serializer/ Deserializer) 或实现不匹配,例如序列化为数字但反序列化为字符串。话虽这么说,这在某些情况下是可行的。结构体应具有相同的名称和相同顺序的字段。类型或者更确切地说Serialize/Deserialize实现也需要支持往返。从Option<()>上面来看,它还取决于Serializer/Deserializer实现是否可以往返它们,即使Serialize/Deserialize实现确实支持它。
许多类型确实尝试支持往返,因为这是最常见的期望。