我有一个包含未知密钥的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
?
答案 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)]