实现 Deserialize
Deserialize
trait 如下所示:
这个方法的作用是通过为 Deserializer
提供一个 Visitor
,将类型映射到 Serde 数据模型,然后由 Deserializer
驱动 Visitor
来构建类型的实例。
在大多数情况下,Serde 的 derive 能够为您的 crate 中定义的 struct 和 enum 生成适当的 Deserialize
实现。如果您需要对某种类型的反序列化行为进行自定义,而派生不支持该行为,可以自己实现 Deserialize
。实现 Deserialize
对于类型而言比实现Serialize
更加复杂。
Deserializer
trait 支持两种入口样式,从而实现不同种类的反序列化。
-
deserialize_any
方法。像 JSON 这样的自描述数据格式能够查看序列化数据并判断其代表的内容。例如,JSON 反序列化器可能看到一个左花括号 ({
) 并知道它看到的是一个 map。如果数据格式支持Deserializer::deserialize_any
,它将根据 input 中判断的类型来驱动 Visitor。JSON 在反序列化serde_json::Value
时使用了这种方法,它是能够表示任何 JSON 文档的 enum。不需要知道 JSON 文档中的内容是什么,我们也可以通过Deserializer::deserialize_any
将其反序列化为serde_json::Value
。 -
其他各种
deserialize_*
方法。非自描述格式例如 Postcard 需要告诉输入中包含的是什么内容才能对其进行反序列化。deserialize_*
方法是为反序列器提供关于如何解释下一个输入片段的提示。非自描述格式无法对类似serde_json::Value
这样依赖Deserializer::deserialize_any
的内容进行反序列化。
在实现 Deserialize
时,应避免依赖Deserializer::deserialize_any
,除非需要反序列化器告诉您输入中的类型。要知道,依赖Deserializer::deserialize_any
意味着您的数据类型只能从自描述格式中反序列化,排除了 Postcard 等许多其他格式。
The Visitor trait
Visitor
是由 Deserialize
实例化并传递给 Deserializer
的。然后,Deserializer
会调用 Visitor
上的方法来构造所需类型。
这是一个 Visitor
示例,能够从各种类型中反序列化基本的 i32
。
Visitor
trait 还有许多没有为I32Visitor
实现的方法。如果调用这些方法,将返回类型错误。例如,I32Visitor
没有实现Visitor::visit_map
,因此尝试在输入包含映射时反序列化一个i32 是一个类型错误。
驱动 Visitor
通过向给定的 Deserializer
传递一个 Visitor
来反序列化值。Deserializer
将根据输入数据之间调用 Visitor
的某个方法,这称为 “驱动” Visitor
。
请注意,Deserializer
不一定会遵循类型提示,因此调用 deserialize_i32
并不一定意味着 Deserializer
将调用 I32Visitor::visit_i32
。例如,JSON 将所有有符号整数类型视为相同。JSON Deserializer
将对任何有符号整数调用 visit_i64
,对任何无符号整数调用 visit_u64
,即使提示不同的类型也是如此。