Last time we looked at Vectors which are like fixed size arrays as in C but with much more functionality and today we will look at another data structure called Hash Maps in Rust. Python have Dictionaries and JavaScript have Objects that are the same as Hash Maps.
Hash Maps
Hash Map is a Data Structure that store a value that is associated with a key in the Hash Map. This key can then later be used to access the value that is relative to that key. The type HashMap<K, V>
store the key of type K
and the value of type V
.
Under the hood, Hash Maps use a hashing function to determine how to place these value and keys into the memory. These can be useful when we want to store and retrive data not with an index like numbers but instead with keys. Keys can be anything from numbers to strings etc.
Creating A Hash Map
A new Hash Map can be created using the new()
method and values can be added to it later in the code. But before doing that we have to use
the HashMap
from the collections
part of the standard library.
use std::collection::HashMap;
fn main() {
let mut marks = HashMap::new();
}
To add values to it we use insert
method.
marks.insert(String::from("Tom"), 70);
marks.insert(String::from("Jerry"), 90);
Accessing Values From A HashMap
To access values from a HashMap we use get method on the hashmap with key as the argument to the get method.
marks.get(String::from("Tom")).unwrap(); // 70
Acessing the value from a HashMap has to be done with very carefully as if provided with the keythat does not exist the program will panic. When we call a get method, the HashMap will return the value of type of either Some
or of type None
.
Here the return type of the marks.get
is of Some
type. and to get the value we then use the unwrap
method. This is where the problem is. If we call the unwrap
method on value of type None
the program will panic and crashes. To deal with this we can use conditional statements here.
if marks.contains_key("Tom") {
let toms_marks = marks.get("Tom");
match toms_marks {
x if x < 35 => println!("Failed"),
x if x < 70 => println!("Pass"),
_ => println!("Excellent")
}
}
Ownership In HashMaps
When working with HashMaps we must take that in mind that the Ownership here works the same as anywhere else in Rust. For types with Copy
trait, there is no need to worry. But for owned values like String
when we use the value in HashMap, the HashMap will take the ownership for that value.
Consider the following example from the Official Documentation.
use std::collections::HashMap;
let field_name = String::from("Favorite color");
let field_value = String::from("Blue");
let mut map = HashMap::new();
map.insert(field_name, field_value);
// field_name and field_value are invalid at this point, try using them and
// see what compiler error you get!