[英]Rust Json serialization overlapping responsibilities
我正在學習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(())
})
}
}
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"}
第一種方法是全自動的,但沒有提供足夠的靈活性。 第二個和第三個通過手動指定序列化過程實現相同級別的靈活性。 在我的情況下,我希望將文檔元數據序列化為一個對象,而不是一個數組(這是派生實現給我的)。
問題 :
如果我想手動序列化,我應該選擇哪種方法?為什么?
我是否正確假設方法2將在內存中構建一個Json
枚舉(除了結構本身)並且更適合於大型文檔(多兆字節),而方法3是流式傳輸並且對於大型文檔更安全?
為什么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.