How it works...

As mentioned earlier, a HashMap is a collection to map one type of data to another. You do this by calling insert, and passing your key and its value [9]. If the key already had a value, it will be overwritten. This is why insert returns an Option: if there was a value before, it returns the old value [27], or otherwise None. If you want to make sure that you're not overwriting anything, make sure to check the result of contains_key [16] before inserting your value.

Both get and remove won't crash when called with an invalid key. Instead, they return a Result. In the case of remove, said Result contains the removed value.

As with most collections, you have the options to iterate over your data, by borrowing the key-value pairs[43], borrowing the keys while mutating the values [49], or moving them all [55]. Due to its nature, HashMap additionally allows you three more options: borrowing all values [74], mutating all values [80], or borrowing all keys [68]. You probably noticed that one combination is missing: you cannot mutate a key. Ever. This is part of the contract you sign when using a HashMap. Further down, where we explain how HashMap is implemented, you're going to see that, because the key's hash is actually an index, mutating a key is equivalent to deleting an entry and recreating it. This is reflected nicely in the design choice of not letting you modify keys.

Last but not least, the Entry API lets you access an abstraction of a value that might or might not be there. Most of the time, it's used while being paired with or_insert in order to insert a default value if the key was not found [88]. If you want to insert a default value based on a closure, you can use or_insert_with. Another use for the entry object is to match it against its variants: Occupied, or Vacant. This results in the same thing as calling get directly on a key. Note that in our example, we had to scope the entry access like so:

    {
let age_of_coral = age.entry("coral").or_insert(11);
println!("age_of_coral: {}", age_of_coral);
}
let age_of_coral = age.entry("coral").or_insert(15);
println!("age_of_coral: {}", age_of_coral);

This is because or_insert returns a mutable reference to a value. If we had omitted the scope, the second call of entry would have borrowed our age object at the same time as a mutable reference to it existed, which is an error in Rust's borrowing concept in order to guarantee data race-free access to resources.

If you need to fine-tune your HashMap for performance, you can call your usual friends —with_capacity [60], shrink_to_fit, and reserve are also available for it, and work the same way as in other collections.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.12.186