如何创建值可以是多种类型之一的 Rust HashMap?

Posted

技术标签:

【中文标题】如何创建值可以是多种类型之一的 Rust HashMap?【英文标题】:How do I create a Rust HashMap where the value can be one of multiple types? 【发布时间】:2017-01-01 23:06:26 【问题描述】:

我想制作一个包含多种类型的 JSON 对象。这是结构:


    "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&lt;&amp;str, Encodable&gt;,但这只是另一个错误。这样做的正确方法是什么?

【问题讨论】:

【参考方案1】:

您应该在HashMap 中使用枚举类型作为值。该枚举需要为每种可能的类型(布尔、数字、字符串、列表、映射...)提供一个变体,并为每个变体提供一个适当类型的关联值:

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

幸运的是,已经有了an implementation of a JSON value type,它是serde_json crate 的一部分,它建立在serde crate 之上。

如果您使用 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 是如何做到的,因为我才刚刚开始。 This crate 还可以让您轻松编写 JSON。 我添加了一个示例。为什么你认为这是矫枉过正?这是对 rust 枚举(标记的联合)的非常简单的使用。【参考方案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();

【讨论】:

以上是关于如何创建值可以是多种类型之一的 Rust HashMap?的主要内容,如果未能解决你的问题,请参考以下文章

Rust—数据类型

Rust学习教程15 - 元组tuple

Rust学习教程15 - 元组tuple

如何编写返回多种数据类型值的Java函数?

python之数据类型

rust单元类型