Introduction
So let's learn about Vectors.
A vector allows users to store a variable number of values next to each other in the Heap. This is also the primary difference when compared to arrays. The size of an array must be known during compile-time.
Creating a Vector
This is how we can create a Vector.
let v: Vec<i32> = Vec::new();
We can also declare Vectors using macro
let v = vec![1, 2, 3];
Updating Vectors
Below is how we can add elements into the Vector.
let mut v = Vec::new();
v.push(1);
v.push(2);
v.push(3);
Reading Values of Vectors
This is how we can read values of a Vector.
fn main() {
let v = vec![1, 3, 5, 7];
let third_elem = &v[2];
println!("{}", third_elem); // 5
}
But this is not considered the right way, because we may try to access an element outside the Vector, because in Vectors the size is dynamic.
fn main() {
let v = vec![1, 3, 5, 7];
let third_elem = &v[22];
println!("{}", third_elem);
}
In this case we'll get below error:
thread 'main' panicked at src/main.rs:4:24:
index out of bounds: the len is 4 but the index is 22
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
The error message correctly highlights the problem.
Hence using the .get() function is a better way to access values of Vectors.
fn main() {
let v = vec![1, 3, 5, 7];
let third_elem: Option<&i32> = v.get(2);
match third_elem {
Some(third_elem) => println!("{}", third_elem),
None => println!("Value is out of bounds."),
}
}
We're using the Option type knowing that the value may or maynot be present. And the error is handled correctly.
Iterating Over Vectors
This is how we iterate over Vectors. Very simple!
fn main() {
let v = vec![1, 3, 5, 7];
for elem in &v {
println!("{elem}");
}
}
In mutable Vectors, we can also change the elements.
fn main() {
let mut v = vec![1, 3, 5, 7];
for elem in &mut v {
*elem *= 2;
println!("{elem}");
}
}
This is very similar to pointers in C
Can We Store Multiple Types in Vectors?
Unfortunately we cannot store multiple types in Vectors. Because multiple types have varied memory consumption, and it causes issues in Heap memory allocation for the Vector in compile-time.
But there is a hack!
enum Number {
Integer(i32),
Float(f64),
}
fn main() {
let mut numeric_vector: Vec<Number> = Vec::new();
numeric_vector.push(Number::Integer(42));
numeric_vector.push(Number::Float(3.14));
numeric_vector.push(Number::Integer(-10));
for num in &numeric_vector {
match num {
Number::Integer(value) => {
println!("{}", value);
}
Number::Float(value) => {
println!("{}", value);
}
}
}
}
This is a simple example of how we can create a Vector that can store both Integers & Floats using enum. Because all elements in the enum are of the same enum type.
Conclusion
That's all about you need to know about Vectors for now. We'll know more in the future articles because we'll be using them everywhere. Cheers!