Rust’s standard library includes a number of very useful data structures called collections. Unlike the built-in array and tuple types, the data these collections point to is stored on the heap, which means the amount of data does not need to be known at compile time and can grow or shrink as the program runs.
This document covers the three most common collections in Rust:
- Vector (
Vec<T>): A growable list of values of the same type. - String (
String): A growable, mutable, owned, UTF-8 encoded string type. - Hash Map (
HashMap<K, V>): A collection of key-value pairs.
1. Vectors (Vec<T>)
A vector, or Vec<T>, allows you to store a variable number of values of a single type next to each other in memory.
Creating a Vector
// Create an empty vector
let v: Vec<i32> = Vec::new();
// Create a vector with initial values using the `vec!` macro
let v = vec![1, 2, 3];
Updating a Vector
You can add elements to a vector using the push method. The vector must be mutable.
let mut v = Vec::new();
v.push(5);
v.push(6);
v.push(7);
Reading Elements from a Vector
There are two ways to access elements: indexing and the get method.
let v = vec![1, 2, 3, 4, 5];
// Using indexing (panics if index is out of bounds)
let third: &i32 = &v[2];
println!("The third element is {}", third);
// Using the get method (returns an Option<&T>)
match v.get(2) {
Some(third) => println!("The third element is {}.", third),
None => println!("There is no third element."),
}
Iterating Over a Vector
You can iterate over the elements of a vector to perform an action on each one.
let v = vec![100, 32, 57];
for i in &v {
println!("{}", i);
}
// Iterate over mutable references to change values
let mut v = vec![100, 32, 57];
for i in &mut v {
*i += 50; // Use the dereference operator (*) to get the value
}
2. Strings (String)
Rust has two main string types: String and the string slice &str. A String is a growable, mutable, owned, UTF-8 encoded string type. A &str is an immutable reference to a sequence of UTF-8 bytes.
Creating a String
// Create an empty string
let mut s = String::new();
// Create a string from a string literal
let s = "initial contents".to_string();
// or
let s = String::from("initial contents");
Updating a String
A String can grow in size and its contents can be changed.
let mut s = String::from("foo");
// Append a string slice
s.push_str("bar"); // s is now "foobar"
// Append a single character
s.push('!'); // s is now "foobar!"
// Concatenate with the `+` operator (takes ownership of the first string)
let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = s1 + &s2; // s1 has been moved and can no longer be used
3. Hash Maps (HashMap<K, V>)
A HashMap<K, V> stores a mapping of keys of type K to values of type V. It’s implemented using a hash table.
Creating a Hash Map
use std::collections::HashMap;
// Create an empty hash map
let mut scores = HashMap::new();
// Insert key-value pairs
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);
Accessing Values
You can get a value out of a hash map by providing its key to the get method.
use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
let team_name = String::from("Blue");
let score = scores.get(&team_name).copied().unwrap_or(0); // .copied() converts Option<&i32> to Option<i32>
println!("The score is: {}", score);
Iterating Over a Hash Map
You can iterate over the key-value pairs in a hash map.
use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);
for (key, value) in &scores {
println!("{}: {}", key, value);
}
Updating a Value Based on the Old Value
A common use case is to check if a key exists and, if not, insert a value. The entry API is perfect for this.
use std::collections::HashMap;
let text = "hello world wonderful world";
let mut map = HashMap::new();
for word in text.split_whitespace() {
let count = map.entry(word).or_insert(0);
*count += 1;
}
println!("{:?}", map); // {"world": 2, "hello": 1, "wonderful": 1}