繁体   English   中英

Rust Json序列化重叠职责

[英]Rust Json serialization overlapping responsibilities

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

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

  1. 推导可编码特征

  2. 手动实施ToJson特质

  3. 手动实现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(())
    })
  }
}

Rust围栏: 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"}

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

问题

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

  3. 我是否正确假设方法2将在内存中构建一个Json枚举(除了结构本身)并且更适合于大型文档(多兆字节),而方法3是流式传输并且对于大型文档更安全?

  4. 为什么rust stdlib使用方法3甚至是原语,而不是在内部使用方法2?

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

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

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

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

是。 ToJson创建整个对象的嵌套Json枚举,而Encodable流式传输到Writer

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

为什么rust stdlib使用方法3甚至是原语,而不是在内部使用方法2?

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM