簡體   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