The original title: Rust vectors links: the original saidvandeklundert.net/learn/2021-… Praying for Rust

What is vector?

A vector can be thought of as an array that can be dynamically resized. It is a data structure that can hold a list of elements that must be of the same type in the same vector. You can also use the enum type if necessary to store different types of elements in a vector (more on that later).

In Rust, a vector consists of three parts:

  • A pointer to the vector data on the heap
  • The length of the
  • capacity

These parameters are stored in a structure. Vector provides a lot of convenience when working with internal sequences of elements, as we’ll see later.

Let’s start by creating a vector:

let mut vec: Vec<i32> = Vec::with_capacity(6);
vec.push(1);
vec.push(2);
Copy the code

Here we use with_capacity, although it is not required, Rust recommends that we specify the expected capacity of the vector as much as possible. Using the previous definition, we have an empty vector with length 0 and capacity 6. Next, we add two elements to the vector. The vector now contains the value [1,2], at which point the length becomes 2 and the capacity remains the same. Our vector looks like this:

To better understand vector, we can print several of its properties on the screen:

println!("-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -");
println!("Values inside vec: {:? }", vec);
println!("Length of the vec: {:? }", vec.len());
println!("Capacity of the vec: {:? }", vec.capacity());
println!("-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -");
Copy the code

The code output is as follows:

-------------------------------------------- Values inside vec: [1, 2] Length of the vec: 2 Capacity of the vec: 6 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -Copy the code

We print the length and capacity of the vector in our code.

Now, if we are going to put five more elements into the vector and the number of elements exceeds the vector’s capacity, Rust will resize the vector. The adjustment process is to create a new vector with twice the current size and copy the elements from the old vector. To see this action, we can execute the following code:

let mut vector = vec![3.4.5.6.7];
vec.append(&mut vector);
println!("-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -");
println!("Length of the vec: {:? }", vec.len());
println!("Capacity of the vec: {:? }", vec.capacity());
println!("-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -");
Copy the code

After executing the above code, we should get the following information:

-------------------------------------------- Length of the vec: 7 Capacity of the vec: 12 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -Copy the code

Common operations on vector

Here are some examples of how to use vector. Much of the post-operation information about vector is detailed in comments, which are (mostly) printed in println! (” {:? }”, x) statement to print the variable. For simplicity, I removed the print statement.

First, we create an empty vector and put some elements in it:

let mut vector: Vec<i32> = Vec::new(); / / []
vector.push(0); / / [0]
vector.push(1); / / [0, 1]
vector.push(2); / / [0, 1, 2]
Copy the code

Remove the last element of the vector and return an Option containing the value of the last element:

vector.pop(); // Some(2)
vector; / / [0, 1]
Copy the code

Retrieve a value from a vector:

vector[1] / / 1
Copy the code

The above code will panic when you point to an index location that does not exist. To safely access an index location, we can use.get (or get_mut() to get a mutable reference) :

vector.get(1) // Some(1)
vector.get(100) // None
Copy the code

Let’s create a second vector using macros:

let mut vec = vec![2.2.3.4.5];
vec; // [2, 2, 3, 4, 5]
Copy the code

We use remove to remove elements from veC at an index position:

vec.remove(0);
vec; // [2, 3, 4, 5]
Copy the code

Use the append method to move all the elements in a vector into the vector calling the method:

vector.append(&mut vec);
vec; / / []
vector; // [0, 1, 2, 3, 4, 5]
Copy the code

Check if a vector is empty:

vec.is_empty(); // true
vector.is_empty(); // false
Copy the code

Return the length of a vector:

vector.len(); / / 6
Copy the code

Iterate over a vector. After defining the iterator, we loop through it:

let vecter_iterator = vector.iter();
for elem in vecter_iterator {
    println!("{}", elem);
}
/* 0, 1, 2, 3, 4, 5 */
Copy the code

None of the previous methods modify elements inside the vector. To iterate over and modify elements, we can use the following methods:

let vecter_iterator_m = vector.iter_mut();
for elem in vecter_iterator_m {
    *elem = *elem * 2;
}
println!("{:? }", vector); // [0, 2, 4, 6, 8, 10]
Copy the code

If you want to verify that a value is in a vector:

vector.contains(&200); // false
vector.contains(&2); // true
Copy the code

Insert an element into the vector:

vector.insert(2.1);
vector; // [0, 2, 1, 4, 6, 8, 10]
Copy the code

Sort the vector and perform a binary lookup:

vector.sort()
vector; // [0, 1, 2, 4, 6, 8, 10]
vector.binary_search(&4); // Ok(3)
vector.binary_search(&400); // Err(7)
Copy the code

Resize a vector and fill the empty Spaces with 0:

vector.resize(10.0);
vector; // [0, 1, 2, 4, 6, 8, 10, 0, 0, 0]
Copy the code

We can use the same method to shrink a vector:

vector.resize(2.0);
vector; / / [0, 1]
Copy the code

Variants will store different types within the same vector using Enum Variants:

#[derive(Debug)]
enum ManyAsOne {
    String(String),
    I32(i32),
    F64(f64),}let vec = vec![
    ManyAsOne::I32(65444),
    ManyAsOne::String(String::from("Hello world.")),
    ManyAsOne::String(String::from("Foo bar.")),
    ManyAsOne::F64(3.14159265),
    ManyAsOne::I32(1984)];for elem in vec {
    println!("{:? }", elem);
    match elem {
        ManyAsOne::I32(value) => println!("value: {}", value),
        ManyAsOne::String(value) => println!("value: {}", value),
        ManyAsOne::F64(value) => println!("value: {}", value),
    }
}
Copy the code

Running the above code outputs the following information:

I32(65444)
value: 65444
String("Hello world.")
value: Hello world.
String("Foo bar.")
value: Foo bar.
F64(3.14159265)
value: 3.14159265
I32(1984)
value: 1984
Copy the code

Put a vector into a hashmap:

use std::collections::HashMap;
let mut job_results: HashMap<String.Vec<i32>> = HashMap::new();
job_results.insert(String::from("1"), vec![3.2.2.2.2]);
job_results.insert(String::from("2"), vec![2.3.2.2.2]);
job_results.insert(String::from("3"), vec![2.2.3.2.2]);
job_results;  / / {" 2 ": [2, 3, 2, 2, 2]," 3 ": [2, 2, 3, 2, 2]," 1 ": (3, 2, 2, 2, 2)}
Copy the code

Finally, we can put a vector into a structure:

#[derive(Debug)]
struct Person {
    name: String,
    age: u8,
    interests: Vec<String>,}let mut marie = Person {
    name: String::from("Marie"),
    age: 31,
    interests: vec![
        String::from("Rust"),
        String::from("Python"),
        String::from("History")]}; marie.interests.push(String::from("Astronomy"));
println!("{:? }", marie);
Copy the code

Running the above code outputs the following information:

Person { name: "Marie", age: 31, interests: ["Rust", "Python", "History", "Astronomy"] }
Copy the code