2016-08-25 40 views
2

我想製作一個包含多種類型的JSON對象。這裏的結構:如何創建一個Rust HashMap,其中的值可以是多種類型之一?

{ 
    "key1": "value", 
    "key2": ["val", "val", "val"] 
    "key3": { "keyX": 12 } 
} 

我怎樣才能使HashMap接受所有這些類型?

我想這一點:

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(); 

我知道散列圖沒有足夠的類型信息,但我不知道我怎樣才能使它發揮作用。我曾嘗試在item上設置一個明確的類型,即HashMap<&str, Encodable>,但這只是另一個錯誤。什麼是正確的方法來做到這一點?

回答

7

您應該在您的HashMap中使用枚舉類型作爲值。該枚舉需要爲每個可能的類型各變體的一種變型(布爾型,數字,字符串,列表,地圖等)和相應類型的關聯值:

enum JsonValue<'a> { 
    String(&'a str), 
    VecOfString(Vec<String>), 
    AnotherHashMap(HashMap<&'a str, u32>), 
} 

幸運的是,已經有an implementation of a JSON value type,部分serde_json箱子是在serde箱子上建造的。

這裏是如果你使用的serde_json箱子你的代碼是什麼樣子:

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}} 
} 
+0

你能提供一個例子如何做我發佈在問題中的例子嗎?除了使用枚舉之外,還有別的方法嗎?看起來有點像其他語言的矯枉過正,不知道Rust是如何做的,因爲我剛剛開始。 – Majster

+0

[這個箱子](https://github.com/maciejhirsz/json-rust)也可以讓你很容易地編寫JSON。 – squiguy

+0

我已經添加了一個例子。你爲什麼認爲這是一個矯枉過正的問題?這是非常簡單的使用鐵鏽枚舉(標記聯合)。 –

2

這裏是另一種方法可能更可口你。 serde_json crate提供了一種從JSON文字構造serde_json::Value對象的方法。你的例子看起來像這樣:

#[macro_use] 
extern crate serde_json; 

fn main() { 
    let item = json!({ 
     "key1": "value", 
     "key2": ["val", "val", "val"], 
     "key3": { "keyX": 12 } 
    }); 

    let response = serde_json::to_string(&item).unwrap(); 
} 
相關問題