How does one create a HashMap with a default value in Rust?

Answering the problem you have

I am looking to maintain a counter for a set of keys.

Then you want to look at How to lookup from and insert into a HashMap efficiently?. Hint: *map.entry(key).or_insert(0) += 1


Answering the question you asked

How does one create a HashMap with a default value in Rust?

No, HashMaps do not have a place to store a default. Doing so would cause every user of that data structure to allocate space to store it, which would be a waste. You’d also have to handle the case where there is no appropriate default, or when a default cannot be easily created.

Instead, you can look up a value using HashMap::get and provide a default if it’s missing using Option::unwrap_or:

use std::collections::HashMap;

fn main() {
    let mut map: HashMap<char, usize> = HashMap::new();
    map.insert('a', 42);

    let a = map.get(&'a').cloned().unwrap_or(0);
    let b = map.get(&'b').cloned().unwrap_or(0);

    println!("{}, {}", a, b); // 42, 0
}

If unwrap_or doesn’t work for your case, there are several similar functions that might:

  • Option::unwrap_or_else
  • Option::map_or
  • Option::map_or_else

Of course, you are welcome to wrap this in a function or a data structure to provide a nicer API.


ArtemGr brings up an interesting point:

in C++ there’s a notion of a map inserting a default value when a key is accessed. That always seemed a bit leaky though: what if the type doesn’t have a default? Rust is less demanding on the mapped types and more explicit about the presence (or absence) of a key.

Rust adds an additional wrinkle to this. Actually inserting a value would require that simply getting a value can also change the HashMap. This would invalidate any existing references to values in the HashMap, as a reallocation might be required. Thus you’d no longer be able to get references to two values at the same time! That would be very restrictive.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)