gpt4 book ai didi

json - Rust Json 序列化职责重叠

转载 作者:行者123 更新时间:2023-11-29 07:46:55 24 4
gpt4 key购买 nike

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

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

  1. 导出可编码特征

  2. 手动实现ToJson trait

  3. 可编码特征的手动实现

下面的代码说明了所有 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"}

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

问题:

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

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

  4. 为什么 rust stdlib 即使对基元也使用方法 3,而在内部不使用方法 2?

最佳答案

Why do methods 2 and 3 exist at all? I don't understand the reason for the overlap between them. I would expect there to exist only one automatic (deriving) method of serialization and one manual.

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

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

Am I right in assuming that method 2 will build a Json enum in memory (besides the struct itself) and is a worse fit for huge documents (multi megabytes), while method 3 is streaming and safer for huge documents?

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

If I want manual serialization, which method should I choose and why?

Why does rust stdlib use method 3 even for primitives, while not using method 2 internally?

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

关于json - Rust Json 序列化职责重叠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25237590/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com