Rfcs: Quick initializer for maps

Created on 20 Dec 2015  ·  9Comments  ·  Source: rust-lang/rfcs

Especially in tests it can be extremely helpful to quickly initialize a map. Right now, you have to create an empty map and call insert a couple of times.

fn main() {
    let vec = [1, 2, 3, 4];
    print!("{:?}", vec);

    let map = {"foo": 0, "bar": 1};
//              ^^^^^^^^^^^
//              does not work
    print!("{:?}", map);
}

See example at http://is.gd/P0yeNQ

T-lang T-libs

Most helpful comment

A non-duck-typed macro supporting both (all) map types will have to wait until we get generic collection traits, but right now one can use

let map: HashMap<_, _> = vec![
    ("foo", 0),
    ("bar", 1),
].into_iter().collect();

All 9 comments

First, [1, 2, 3, 4] is not a Vec<i32> actually, its an [i32; 4]. There is no literal syntax for vectors, but there is a very ergonomic macro vec!, so you can create a vector with vec![1, 2, 3, 4]. I expect what you're asking for is a similar macro.

There is a third-party crate called maplit which provides macros like this.

This is better suited for a macro, since maps are not that common and such sugar isn't worth it. Also, there are multiple types of maps for different use cases, and they're not hard-coded in the language.

I'm unsure if such a macro belong in the standard library, though.

You are right. I meant to use the !vec macro. Although in my tests it doesn't really matter.

The maplit macros are exactly what I was looking for. However, as a user I am a bit surprised that the !vec macro is in the standard library but hashmap! is not. Feel free to close this issue if you disagree.

Feel free to close this issue if you disagree.

That's not how the RFC process works. Opinions and disagreements _are_ allowed.

However, as a user I am a bit surprised that the !vec macro is in the standard library but hashmap! is not.

I don't hold a particular strong opinion on whether libstd should provide a hashmap macro. On one side, it's a neat "sugar" for initializing hashmaps (which is currently a pain).

On the other side, I would avoid getting libstd bloated with macros, since importing/exporting macros, currently, is odd (you might have noticed that you don't have to import the macros in the standard library, even though they aren't (and cannot be) a part of the prelude). Macros aren't exported/imported in the "usual" way. They belong to a module and are chosen whether to be exported by the parrent module (using #[macro_use]).

See also Nick Cameron's macro syntax proposal: http://www.ncameron.org/blog/macro-plans-syntax/

However, as a user I am a bit surprised that the !vec macro is in the standard library but hashmap! is not.

If I recall correctly, the reasoning was that while vectors are very clearly preferred over other sequential data structures for nearly all use cases, the choice between hashmap and btreemap is less obvious. People were reluctant to preference one with a macro. I don't have a strong opinion.

I use maps a lot less in Rust than I do in dynamic languages like Python or Ruby.

Yes, @withoutboats is right as to why we've historically rejected this. I don't think we currently have an issue open about it, though, so we might as well have this one.

A non-duck-typed macro supporting both (all) map types will have to wait until we get generic collection traits, but right now one can use

let map: HashMap<_, _> = vec![
    ("foo", 0),
    ("bar", 1),
].into_iter().collect();

This is a duplicate of #542

Was this page helpful?
0 / 5 - 0 ratings

Related issues

marinintim picture marinintim  ·  3Comments

3442853561 picture 3442853561  ·  3Comments

mqudsi picture mqudsi  ·  3Comments

3442853561 picture 3442853561  ·  3Comments

Diggsey picture Diggsey  ·  3Comments