#rust
- Vectors allow you to store more than one value in a single data structure that puts all the values next to each other in memory. Vectors can only store values of the same type.
- To create a vector and then add elements to it, we can use the
push
method. - There are two ways to reference a value stored in a vector: via indexing or using the
get
method. When we use theget
method with the index passed as an argument, we get anOption<&T>
that we can use withmatch
. - The
next
method advances the iterator and returns an optional reference to the previous element, eitherSome
(which we unwrap) orNone
at the end of the vector. - We can define an enum whose variants will hold the different value types, and all the enum variants will be considered the same type: that of the enum. Then we can create a vector to hold that enum and so, ultimately, holds different types.
- The type
HashMap<K, V>
stores a mapping of keys of typeK
to values of typeV
using a hashing function, which determines how it places these keys and values into memory. - One way to create an empty hash map is using
new
and adding elements withinsert
.
// use is needed because HashMaps are not included in preclude
use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);
- Just like vectors, hash maps store their data on the heap. Like vectors, hash maps are homogeneous: all of the keys must have the same type as each other, and all of the values must have the same type.
- We can get a value out of the hash map by providing its key to the
get
method. Theget
method returns anOption<&V>
; if there’s no value for that key in the hash map,get
will returnNone
. This program handles theOption
by callingcopied
to get anOption<i32>
rather than anOption<&i32>
, thenunwrap_or
to setscore
to zero ifscores
doesn't have an entry for the key.
let team_name = String::from("Blue");
let score = scores.get(&team_name).copied().unwrap_or(0);
- We can iterate over each key/value pair in a hash map in a similar manner as we do with vectors, using a
for
loop.
for (key, value) in &scores {
println!("{}: {}", key, value);
}
- For types that implement the
Copy
trait, likei32
, the values are copied into the hash map. For owned values likeString
, the values will be moved and the hash map will be the owner of those values. - If we insert a key and a value into a hash map and then insert that same key with a different value, the value associated with that key will be replaced.
- Hash maps have a special API for this called
entry
that takes the key you want to check as a parameter. The return value of theentry
method is an enum calledEntry
that represents a value that might or might not exist.
use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.entry(String::from("Yellow")).or_insert(50);
scores.entry(String::from("Blue")).or_insert(50); // no change
println!("{:?}", scores);
- By default,
HashMap
uses a hashing function called SipHash that can provide resistance to Denial of Service (DoS) attacks involving hash tables. This is not the fastest hashing algorithm available, but the trade-off for better security that comes with the drop in performance is worth it. If you profile your code and find that the default hash function is too slow for your purposes, you can switch to another function by specifying a different hasher.