如何创建 HashMap 文字? [英] How do I create a HashMap literal?

查看:19
本文介绍了如何创建 HashMap 文字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在 Rust 中创建 HashMap 文字?在 Python 中,我可以这样做:

How I can create a HashMap literal in Rust? In Python I can do it so:

hashmap = {
   'element0': {
       'name': 'My New Element',
       'childs': {
           'child0': {
               'name': 'Child For Element 0',
               'childs': {
                   ...
               }
           }
       }
   },
   ...
}

在 Go 中是这样的:

And in Go like this:

type Node struct {
    name string
    childs map[string]Node
}

hashmap := map[string]Node {
    "element0": Node{
        "My New Element",
        map[string]Node {
            'child0': Node{
                "Child For Element 0",
                map[string]Node {}
            }
        }
    }
}

推荐答案

Rust 中没有映射字面量语法.我不知道确切的原因,但我希望有多种数据结构像映射一样(例如 BTreeMapHashMap) 会使选择一个变得困难.

There isn't a map literal syntax in Rust. I don't know the exact reason, but I expect that the fact that there are multiple data structures that act maplike (such as both BTreeMap and HashMap) would make it hard to pick one.

从 Rust 1.51 开始,您可以使用按值数组迭代器和 FromIterator 来收集多种集合:

As of Rust 1.51, you can use by-value array iterators and FromIterator to collect into many kinds of collections:

use std::array::IntoIter;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::iter::FromIterator;

fn main() {
    // Rust 1.53
    let s = Vec::from_iter([1, 2, 3]);
    println!("{:?}", s);

    // Rust 1.51
    let s = Vec::from_iter(IntoIter::new([1, 2, 3]));
    println!("{:?}", s);

    let s = BTreeSet::from_iter(IntoIter::new([1, 2, 3]));
    println!("{:?}", s);

    let s = HashSet::<_>::from_iter(IntoIter::new([1, 2, 3]));
    println!("{:?}", s);

    let s = BTreeMap::from_iter(IntoIter::new([(1, 2), (3, 4)]));
    println!("{:?}", s);

    let s = HashMap::<_, _>::from_iter(IntoIter::new([(1, 2), (3, 4)]));
    println!("{:?}", s);
}

请注意,在 Rust 1.53 中,并不总是需要 std::array::IntoIter.

Note that in Rust 1.53, std::array::IntoIter isn't always needed.

这个逻辑可以被包装回一些语法糖的宏:

This logic can be wrapped back into a macro for some syntax sugar:

use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};

macro_rules! collection {
    // map-like
    ($($k:expr => $v:expr),* $(,)?) => {{
        use std::iter::{Iterator, IntoIterator};
        Iterator::collect(IntoIterator::into_iter([$(($k, $v),)*]))
    }};
    // set-like
    ($($v:expr),* $(,)?) => {{
        use std::iter::{Iterator, IntoIterator};
        Iterator::collect(IntoIterator::into_iter([$($v,)*]))
    }};
}

fn main() {
    let s: Vec<_> = collection![1, 2, 3];
    println!("{:?}", s);

    let s: BTreeSet<_> = collection! { 1, 2, 3 };
    println!("{:?}", s);

    let s: HashSet<_> = collection! { 1, 2, 3 };
    println!("{:?}", s);

    let s: BTreeMap<_, _> = collection! { 1 => 2, 3 => 4 };
    println!("{:?}", s);

    let s: HashMap<_, _> = collection! { 1 => 2, 3 => 4 };
    println!("{:?}", s);
}

这些解决方案避免了不必要的分配和重新分配.

These solutions avoid both unneeded allocation and reallocation.

另见:

您可以创建一个宏来为您完成这项工作,如为什么这个 rust HashMap 宏不再起作用?.这是该宏稍微简化并具有足够的结构以使其可在操场上运行:

You can create a macro to do the job for you, as demonstrated in Why does this rust HashMap macro no longer work?. Here is that macro simplified a bit and with enough structure to make it runnable in the playground:

macro_rules! map(
    { $($key:expr => $value:expr),+ } => {
        {
            let mut m = ::std::collections::HashMap::new();
            $(
                m.insert($key, $value);
            )+
            m
        }
     };
);

fn main() {
    let names = map!{ 1 => "one", 2 => "two" };
    println!("{} -> {:?}", 1, names.get(&1));
    println!("{} -> {:?}", 10, names.get(&10));
}

这个宏避免分配不需要的中间Vec,但它不使用HashMap::with_capacity 所以在添加值时可能会有一些无用的 HashMap 重新分配.计算值的宏的更复杂版本是可能的,但性能优势可能不是宏的大多数用途所受益的.

This macro avoids allocating an unneeded intermediate Vec, but it doesn't use HashMap::with_capacity so there may be some useless reallocations of the HashMap as values are added. A more complicated version of the macro that counts the values is possible, but the performance benefits are probably not something most uses of the macro would benefit from.

这篇关于如何创建 HashMap 文字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆