9

I can use vec![1,2,3] to build a vector.
Can I build a hashmap in Rust a bit like this:

hashmap![("key", "value")]

without creating a separate variable and calling .insert() each time?

Sergey
  • 19,487
  • 13
  • 44
  • 68

2 Answers2

14

If you create a macro

macro_rules! hashmap {
    ($( $key: expr => $val: expr ),*) => {{
         let mut map = ::std::collections::HashMap::new();
         $( map.insert($key, $val); )*
         map
    }}
}

then you call it like following

let map= hashmap!["key1" => "value1", "key2" => "value2"];
Szymon Roziewski
  • 956
  • 2
  • 20
  • 36
9

One solution is to rely on an array and collect() it into a HashMap:

fn main() {
    let map: std::collections::HashMap<_, _> = [("foo", 0), ("bar", 1)]
        .iter()
        .cloned()
        .collect();

    println!("{:?}", map);
}

It outputs:

{"foo": 0, "bar": 1}

collect() From the Rust documentation:

Transforms an iterator into a collection.

collect() can take anything iterable, and turn it into a relevant collection. This is one of the more powerful methods in the standard library, used in a variety of contexts.

The most basic pattern in which collect() is used is to turn one collection into another. You take a collection, call iter() on it, do a bunch of transformations, and then collect() at the end.

  • 2
    It would be better not to use the vector to avoid unnecessary memory allocation. The array works fine with cloneable types: `[("foo", 0), ("bar", 1)].iter().cloned().collect()` – aSpex Dec 14 '16 at 15:19
  • Yes. It's corrected. –  Dec 14 '16 at 15:47