这几天在捣鼓Serde::Deserializer,发现有一点难理解。死磕了7、8小时后,算是明白了它的原理。
如果你也想自己捣鼓,你可以试著把下列两个网址所有代码(代码是以1个简单json反序列化的例子来举例说明Deserializer怎么用)复制到Idea或vscode等ide,在想要跟踪的地方设断点或打印信息,然后运行代码中的测试用例,多运行几天就能够逐渐理解Deserializer怎么用:
下面我试著写一下它的原理,帮助后来者:
- 假设我想要透过调用new_instance::<T>()->T,期望它返回T类的实例(T类的字段,凡是数字的设为0,bool设为false,String设为"".to_owned(),其它类则递归地返回它的实例)。则new_instance()代码如下图(1)所示:
- 上图(1)被调用后,运行到T::deserialize(&mut deserializer)后,Deserializer的fn deserialize_struct(fields)首先被调用,如上图(2)所示;在fn deserialize_struct(fields)中可以取到T的struct名称(name: &str)及所有字段名(fields: &[&str]);我第1次尝试到这里就卡壳了;请继续看下去:
- 接下来,我们希望一个字段一个字段地(不需要按字段顺序)返回该字段的类型和值,怎么办呢?需要借助一个实现de::MapAccess的MapAccesses类,这个类只有两个方法fn next_key_seed() 和 fn next_value_seed();
- 当执行到visitor.visit_map(MapAccesses::new(self)),会将Deserializer自己传入MapAccesses中,然后反复调用next_key_seed()及next_value_seed(),如上图(3)所示,直到next_key_seed返回Ok(None)停止;
- 从函数名可以判断出next_key_seed()及next_value_seed()分别要返回字段类型及字段值,问题是它们分别返回泛型K::Value和V::Value,不太容易理解它们是什么!?
未完待续………