使用rustc_serialize反序列化JSON对象:为什么我需要实现PartialEq?

时间:2015-09-01 12:02:13

标签: json rust

我有一个包含未知密钥的JSON对象的文件。我想将这个对象解码为一个结构,但不了解如何声明这个结构。

extern crate rustc_serialize;
use rustc_serialize::json;
use std::collections::BTreeMap;

#[derive(RustcDecodable, Debug)]
struct MyStruct {
    foo: u8,
    bar: Vec<String>,
}

let raw_json = r#"{
    "A": {
        "foo": 2,
        "bar": ["a", "b"],
    },
    "C": {
        "foo": 1,
        "bar": ["c", "d"],
    },
    :
}"#;

let j: BTreeMap<String, MyStruct> = json::decode(&raw_json).unwrap();
println!("{:?}", j.get("A").unwrap());

发生以下错误:

error: the trait `core::cmp::PartialEq` is not implemented for the type `MyStruct` [E0277]
    let j: BTreeMap<String, MyStruct> = json::decode(&raw_json).unwrap();
                                        ^~~~~~~~~~~~

我是否必须亲自为Decodable实施MyStruct

2 个答案:

答案 0 :(得分:3)

json::decode定义为:

pub fn decode<T: Decodable>(s: &str) -> DecodeResult<T>

这意味着给定一个字符串切片,它将尝试解码为用户指定的类型,只要该类型实现Decodable即可。在Decodable的页面上,您可以看到它的所有实现,包括BTreeMap的实现:

impl<K: Decodable + PartialEq + Ord,
     V: Decodable + PartialEq>
Decodable for BTreeMap<K, V>

这表明为了解码为BTreeMap,地图中的键和值都需要为PartialEq。但是,我不清楚为什么实际需要它。 BTreeMap应该只要求密钥为Ord而根本不关心价值。为此,我打开了a pull request来删除这些边界,它被接受了! ^ _ ^我猜这意味着边界本来可能只是一个错字。

答案 1 :(得分:0)

@Shepmaster提示的简单答案是要么实现PartialEq特征,要么导出它,如错误消息所示:

#[derive(RustcDecodable, PartialEq, Debug)]