考虑以下代码:
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
的表示中包含一些其他的、极端情况的、可能与平台相关的、不可预见的信息导致两种表示不兼容?
最佳答案
一般来说,不,你不能指望这能起作用。原因是 Serde 和任何反序列化器都不能保证您可以往返数据( source )。这意味着如果您在两个地方使用相同的结构,您甚至不能指望它在所有情况下都有效。
例如 JSON 无法往返 Option<()>
像 bincode 这样非自描述的格式不支持未标记的枚举。
类型签名中没有任何内容强制往返。
以下是反序列化可能失败的一些原因:
- 使用
skip_serializing_none
具有非自描述格式( serde #1732 )。 - 任何调用
deserialize_any
的东西,例如未标记、相邻标记或内部标记的枚举 ( serde #1762 )。 - 反序列化期间借用,例如
&'de str
或&'de [u8]
。serde_json
仅支持&'de str
如果没有转义序列并且从不支持&'de [u8]
. - 某些格式无法序列化某些类型,例如 JSON 不支持结构体作为映射键,而 bincode 仅支持已知长度的序列 ( bincode #167 )。
- 类型仅实现其中一个特征 (
Serializer
/Deserializer
) 或实现不匹配,例如序列化为数字但反序列化为字符串。
话虽这么说,这在某些情况下可以工作。结构体应具有相同的名称和相同顺序的字段。类型或者更确切地说 Serialize
/Deserialize
实现还需要支持往返。与Option<()>
从上面来看,它还取决于 Serializer
/Deserializer
实现,如果你可以往返它们,即使 Serialize
/Deserialize
实现确实支持它。
许多类型确实尝试支持往返,因为这是最常见的期望。
关于rust - 我可以相信两个相同结构的序列化是相同的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69120880/