Masai Mahapa

30 days of Rust - Day Six - Vectors

30 days of rust - day Six So far, most of the data we've had to deal with were single values such as let x= 1;. This works for most cases, but in order for us to build more useful programs we need to store collections of data . (e.g to represent a shopping cart 🛒 ).

Today, I'm learning about Vectors.

Day 6- Vectors

A vector is an array (list) on steroids 💪🏽. They allow us to store a variable number of items next to each other in memory, for as long as they are of the same type.

Lets create a vector;

fn main() {
   let mut fruits_vec: Vec<String> = Vec::new();
   fruits_vec.push(String::from("apples"));
   fruits_vec.push(String::from("banana"));
}

The code above creates a new vector called fruits_vec which holds items of the type String. In order to add new fruits to fruits_vec we use the .push method;

fruits_vec.push(String::from("apples"));

If we know ahead of time some of the values our vector will hold, we can instead let Rust infer (figure out) what type the vector holds by using the vec! macro like;

let fruits_vec = vec![String::from("apples"),
String::from("apples")];

Getting Elements

In order to get elements from a vector we can either use the indexing or get method.

let second_element = &fruits_vec[1];

Or secondly, and most preferably;

match fruits_vec.get(1){
       Some(second_element) => println!("The second element is {}", second_element),
       None => println!("Got nothing")
   }

The reason why using the .get(1) over [1], is to reduce the chances of our program crashing. .get() returns an Option<T> which allows us to handle unexpected outputs without crashing the program.

The code below will crash our program;

let seventieth_element = &fruits_vec[70];

The error we get is;

thread 'main' panicked at 'index out of bounds: the len is 2 but the index is 77'

This basically means that we are trying to get an element that does not exist.

References and Vectors

Remember the concept of ownership that we covered on day 2? It comes back into play here. The rule of borrowing was that we can't have a mutable and immutable reference in the same scope.

   let mut fruits_vec: Vec<String> = Vec::new();
   fruits_vec.push(String::from("apples"));
   fruits_vec.push(String::from("banana"));
 
   let banana = &fruits_vec[1];
 
   fruits_vec.push(String::from("Tomato")); // program will not run
 
   print!("Man i love {}", banana)

Let's take it a step at a time;

  1. fruits_vec is mutable.
  2. banana is a reference to the second value of fruits_vec
  3. We try to add Tomato 🍅 to the end of fruits_vec, causing an error.

The reason is because vectors can grow at runtime. So when we try to add an element to a vector and it has no more space, the elements inside are copied to a bigger space on the heap (memory). This would leave banana referencing a piece of memory which has been deallocated.

A simple analogy is you, starting a family with just 2 people. You'd need just a 1 bedroom apartment. As your family grows, you'd move to a bigger house 🏡 to accommodate everyone. So people can't come looking for you at your previous house.

Looping over a vector

In order to loop over each fruit in our vector. We use a for loop;

for fruit in &fruits_vec {
       println!("{}", fruit);
   }

Storing Multiple Types

Is there a hack to get around the fact that Vectors can only contain one type? Yes, we can do so using Enums. Check out my post on Enums for a refresher.

Let's say we would like to store a Microsoft Excel column into a vector. The column has Text, integers as well booleans.

enum SpreadsheetCell {
   Int(i32),
   Boolean(bool),
   Text(String),
}
 
fn main() {
   let row = vec![
       SpreadsheetCell::Int(12),
       SpreadsheetCell::Text(String::from("Masai")),
       SpreadsheetCell::Boolean(true),
   ];
}

Conclusion

This was quite fun. Being able to store many values in a list which can grow feels like a super power. This allows our programs to be increasingly more useful.

Rust is quite strict with it's rules on referencing and borrowing and it will take a while to get used to them, especially when coming to Vectors.

Please let me know what you think of this series of posts and at what day of the challenge you're currently at. I'd also love to share your story if you write/film about it.

Share