问题描述
我想制作一个包含多种类型的JSON对象。这里是结构:
$ p $ $ $ $ $ $ $ $ $ $ $ $ $ $'$'$'$'$'$' val,val,val]
key3:{keyX:12}
}
我怎样才能制作一个 HashMap
它接受所有这些类型?
我试着这样做:
let item = HashMap :: new();
item.insert(key1,someString); // type是& str
item.insert(key2,someVecOfStrings); // type是Vec< String>
item.insert(key3,someOtherHashMap); //类型是HashMap<& str,u32>
let response = json :: encode(& item).unwrap();
我知道散列图没有足够的类型信息,但我不知道如何可以使它工作。我已经尝试在项目
中设置显式类型,它是 HashMap<& str,Encodable>
,但它只是另一个错误。这样做的正确方法是什么?
您应该在您的 HashMap中
。该枚举需要针对每种可能的类型(布尔,数字,字符串,列表,映射...)以及每种变体的相应类型的相关值有一个变体:
枚举JsonValue<'a> {
String(&'a str),
VecOfString(Vec< String>),
AnotherHashMap(HashMap<&'a str,u32>),
}
幸运的是,,是箱子,它建立在 crate。
这是您的代码在使用serde_json箱时的外观:
extern crate serde_json;
使用serde_json :: {Value,Map,Number};
fn main(){
let mut inner_map = Map :: new();
inner_map.insert(x.to_string(),Value :: Number(Number :: from(10u64)));
inner_map.insert(y.to_string(),Value :: Number(Number :: from(20u64)));
let mut map = Map :: new();
map.insert(key1.to_string(),Value :: String(test.to_string()));
map.insert(
key2.to_string(),
Value :: Array(vec![
Value :: String(a.to_string()),
Value :: String(b.to_string()),
]),
);
map.insert(key3.to_string(),Value :: Object(inner_map));
println!({},serde_json :: to_string(& map).unwrap());
// => {key1:test,key2:[a,b],key3:{x:10,y:20}}
}
I want to make a JSON object which includes multiple types. Here's the structure:
{
"key1": "value",
"key2": ["val", "val", "val"]
"key3": { "keyX": 12 }
}
How can I make a HashMap
which accepts all these types?
I'm trying this:
let item = HashMap::new();
item.insert("key1", someString); //type is &str
item.insert("key2", someVecOfStrings); //type is Vec<String>
item.insert("key3", someOtherHashMap); //Type is HashMap<&str, u32>
let response = json::encode(&item).unwrap();
I know that the hash map does not have enough type info, but I'm not sure how I can make it work. I have tried setting an explicit type on item
which was HashMap<&str, Encodable>
but then it's just another error. What is the correct way to do this?
You should use an enum type as value in your HashMap
. That enum needs to have a variant for each possible type (boolean, number, string, list, map...) and an associated value of appropriate type for each variant:
enum JsonValue<'a> {
String(&'a str),
VecOfString(Vec<String>),
AnotherHashMap(HashMap<&'a str, u32>),
}
Fortunately, there already is an implementation of a JSON value type, part of the serde_json crate which is built on the serde crate.
Here is how your code would look if you used the serde_json crate:
extern crate serde_json;
use serde_json::{Value, Map, Number};
fn main() {
let mut inner_map = Map::new();
inner_map.insert("x".to_string(), Value::Number(Number::from(10u64)));
inner_map.insert("y".to_string(), Value::Number(Number::from(20u64)));
let mut map = Map::new();
map.insert("key1".to_string(), Value::String("test".to_string()));
map.insert(
"key2".to_string(),
Value::Array(vec![
Value::String("a".to_string()),
Value::String("b".to_string()),
]),
);
map.insert("key3".to_string(), Value::Object(inner_map));
println!("{}", serde_json::to_string(&map).unwrap());
// => {"key1":"test","key2":["a","b"],"key3":{"x":10,"y":20}}
}
这篇关于如何创建一个Rust HashMap,其中的值可以是多种类型之一?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!