Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Not understanding the match function of a HashMap.entry()

I am just starting to learn Rust. The entry method an Entry enum, which can be accessed via the match function. But then I don’t get why it doesn’t compile and it panics.
Can someone explain please what I’m understanding wrong?

let mut scores: HashMap<String, u32> = HashMap::new();

scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);

let a = 10;
match scores.entry("poneyland".to_string()) {
    Occupied(o) => o.remove_entry(),
    Vacant(o) =>  o.insert(37),
}

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

But then I don’t get why it doesn’t compile and it panics.

It can’t both fail to compile and panic, since panic is a runtime behaviour. Either way, when there is an error it is usually a good idea to post it, as that makes diagnostic much easier, especially in Rust which generally has pretty helpful error messages.

In this case, the compilation error tells you exactly what’s what:


error[E0308]: `match` arms have incompatible types
  --> src/main.rs:15:22
   |
13 | /     match scores.entry("poneyland".to_string()) {
14 | |         Occupied(o) => o.remove_entry(),
   | |                        ---------------- this is found to be of type `(String, u32)`
15 | |         Vacant(o) => o.insert(37),
   | |                      ^^^^^^^^^^^^ expected tuple, found `&mut u32`
16 | |     }
   | |_____- `match` arms have incompatible types
   |
   = note:          expected tuple `(String, u32)`
           found mutable reference `&mut u32`

You pretty much just need to read the message, and possibly the expanded document.

What it boils down to is a rust match is an expression, meaning it has a value of a specific type, meaning all arms must have values of the same type (or a compatible type e.g. !).

Here, as the compiler error tells you, in one arm you’re calling remove_entry which returns a tuple of (key, value), while in the other arm you’re calling insert which returns a mutable reference to the inserted value.

These types are obviously not compatible.

The easiest way to fix this is to make them compatible by… suppressing the results entirely since you’re not using them: convert the arm expressions to arm blocks and terminate the expressions with ;. That makes the expressions into statements and suppresses their value, implicitly returning () instead:

    match scores.entry("poneyland".to_string()) {
        Occupied(o) => {
            o.remove_entry();
        }
        Vacant(o) => {
            o.insert(37);
        }
    }

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=1b885daa2a4eaa6d9d7c366753f6c2aa

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading