Trouble with HashMaps

Hey guys,

I've been learning rust for a couple of weeks now (mainly through "The Rust Programming Language" book) and I'm loving it. My favorite language has been C and I feel like Rust is the upgrade I've been craving for a loooong time :smile:

To the point: I'm having trouble with one of the exercises from the book and was hoping some of you could explain it to me. Here is my code:

use std::io;
use std::collections::HashMap;

fn main() {
    println!("--- Employers Database ---");

    let mut data_base: HashMap<String, Vec<String>> = HashMap::new();

    loop {
        let mut input = String::new();

        io::stdin().read_line(&mut input)
            .expect("Error reading the command");

        let command: Vec<&str> = input.trim().split(" ").collect();

        if command.len() == 4
            && command[0] == "add"
            && command[2] == "to"
        {
            let employee = String::from(command[1]);
            let department = String::from(command[3]);

            match data_base.get(&department) {
                Some(list) => list.push(employee),
                None => data_base.insert(department, vec![employee]),
            }

        }
        else if command.len() == 2
            && command[0] == "retrieve"
        {
            match command[1] {
                "all" => println!("get the whole data base"),
                _ => println!("get data base for department {}", command[1]),
            }
        }
        else if command.len() == 1
            && command[0] == "quit"
        {
            break;
        }
        else
        {
            println!("Unknown command");
        }
    }
}

The compiler tells me that the variable list (inside the match arm) is "found to be of type ()", and I really don't understand why... any help?

Thanks!

Vec::push returns () but HashMap::insert returns Option<V>. To fix this you can do either

None => drop(data_base.insert(department, vec![employee]))

or

None => { data_base.insert(department, vec![employee]); }

In the second way, the semicolon is semantically important

I'd personally recommend the functional approach here. You can replace the whole match with:

data_base.entry(department).or_default().push(employee);
1 Like