Rust Json序列化重叠责任

我正在学习Rust中的Json序列化,特别是如何将Rust对象序列化为Json。

目前我看到3个将结构实例转换为Json的方法:

  • 派生可编码特性

  • ToJson特征的手动实现

  • 手动实现Encodable特征

  • 以下代码说明了所有3种方法:

    extern crate serialize;
    
    use serialize::{Encoder, Encodable, json};
    use serialize::json::{Json, ToJson};
    use std::collections::TreeMap;
    
    fn main() {
      let document = Document::new();
      let word_document = WordDocument::new();
      println!("1. Deriving `Encodable`: {}", json::encode(&document));
      println!("2. Manually implementing `ToJson` trait: {}", document.to_json());
      println!("3. Manually implementing `Encodable` trait: {}", json::encode(&word_document));
    }
    
    #[deriving(Encodable)]
    struct Document<'a> {
      metadata: Vec<(&'a str, &'a str)>
    }
    
    impl<'a> Document<'a> {
      fn new() -> Document<'a> {
        let metadata = vec!(("Title", "Untitled Document 1"));
        Document {metadata: metadata}
      }
    }
    
    impl<'a> ToJson for Document<'a> {
      fn to_json(&self) -> Json {
        let mut tm = TreeMap::new();
        for &(ref mk, ref mv) in self.metadata.iter() {
          tm.insert(mk.to_string(), mv.to_string().to_json());
        }
        json::Object(tm)
      }
    }
    
    struct WordDocument<'a> {
      metadata: Vec<(&'a str, &'a str)>
    }
    
    impl<'a> WordDocument<'a> {
      fn new() -> WordDocument<'a> {
        let metadata = vec!(("Title", "Untitled Word Document 1"));
        WordDocument {metadata: metadata}
      }
    }
    
    impl<'a, E, S: Encoder<E>> Encodable<S, E> for WordDocument<'a> {
      fn encode(&self, s: &mut S) -> Result<(), E> {
        s.emit_map(self.metadata.len(), |e| {
          let mut i = 0;
          for &(ref key,  ref val) in self.metadata.iter() {
            try!(e.emit_map_elt_key(i, |e| key.encode(e)));
            try!(e.emit_map_elt_val(i, |e| val.encode(e)));
            i += 1;
          }
          Ok(())
        })
      }
    }
    

    锈围栏:http://is.gd/r7cYmE

    结果:

    1. Deriving `Encodable`: {"metadata":[["Title","Untitled Document 1"]]}
    2. Manually implementing `ToJson` trait: {"Title":"Untitled Document 1"}
    3. Manually implementing `Encodable` trait: {"Title":"Untitled Word Document 1"}
    

    第一种方法是全自动的,但不能提供足够的灵活性。 第二个和第三个通过手动指定序列化过程来实现相同级别的灵活性。 在我的情况下,我希望文档元数据被序列化为一个对象,而不是数组(这是派生实现给我的)。

    问题

  • 为什么方法2和方法3都存在? 我不明白他们之间重叠的原因。 我希望那里只存在一个序列化和一个手册的自动(派生)方法。
  • 如果我想要手动序列化,我应该选择哪种方法,为什么?

  • 我是否正确地认为方法2会在内存中建立一个Json枚举(除了结构本身),并且对于大型文档(多兆字节)更适合,而方法3对于大型文档更流畅并且更安全?

  • 为什么生锈的stdlib甚至对原语使用方法3,而在内部不使用方法2?


  • 为什么方法2和方法3都存在? 我不明白他们之间重叠的原因。 我希望那里只存在一个序列化和一个手册的自动(派生)方法。

    方法2( ToJson特征)特定于编码JSON。 它返回JSON对象,而不是写入流。 一个使用示例是映射到自定义表示 - 请参阅文档中的此示例。

    方法3(实现Encodable )必须存在才能使方法1工作。

    我是否正确地认为方法2会在内存中建立一个Json枚举(除了结构本身),并且对于大型文档(多兆字节)更适合,而方法3对于大型文档更流畅并且更安全?

    是。 ToJson创建一个嵌套的Json枚举整个对象,而Encodable流写入一个Writer

    如果我想要手动序列化,我应该选择哪种方法,为什么?

    为什么生锈的stdlib甚至对原语使用方法3,而在内部不使用方法2?

    你应该使用Encodable 。 它不是特定于JSON格式,不使用中间表示(因此可以流式传输而不是存储在内存中),并应继续使用添加到库中的新格式。

    链接地址: http://www.djcxy.com/p/80825.html

    上一篇: Rust Json serialization overlapping responsibilities

    下一篇: How to Draw chart in windows phone 8 or 8.1 without using external library?