Generic collection type – dynamic array vector

The so-called dynamic array, or Vec, allows us to store multiple values of the same type in a single data structure, which can be understood as array in TS.

Creating a dynamic array

Create an array with members of type I32 using the Vec structure:

let v: Vec<i32> = Vec::new();
println!("{:? }", v) / / []
Copy the code

You can also use VEC! Macros create arrays:

/ / the vec! Arrays can be created quickly, and the compiler will automatically infer that Vec is of type Vec
      
let v2 = vec![1.2.3];
println!("{:? }", v2); / / [1, 2, 3]

// The compiler uses the first element type to determine the veC type
// If the following type is different, an error will be reported
let v2 = vec![1.2."3"]; // The third member should be of type I32

// So an error will be reported if the first element is not present at initialization because the compiler cannot infer the type
let v3 = vec![] // An error was reported, the member type could not be inferred
Copy the code

Update the array

To add elements to a dynamic array after it is created, we can use the push method:

// Add the muT keyword because you want to change the contents of the array
let mut v4 = vec![1];

// v4 is inferred to be Vec
      
       , so only i32 can be added here
      
v4.push(2);

// Adding other types will result in an error
v4.push("3"); // An i32 type is expected
Copy the code

Destruction of arrays

When an array is destroyed out of scope, its members are also destroyed:

{
  let v5 = vec![1.2.3];
  println!("{:? }", v5); / / [1, 2, 3]
} // After the scope is executed, V5 is destroyed, along with all members
Copy the code

Reading an array member

There are two ways to access a member of a dynamic array:

let v6 = vec![1.2.3.4.5];

// Access the element with index 2 and get the reference to the member
let third: &i32 = &v6[2];
println!(The third member is: {}, third); / / 3

// Access a member that does not exist
let no_exist: &i32 = &v6[100]; // An error was reported. The index exceeded the array length
Copy the code

There is another way to access using the get function, which returns the Option type:

// Get returns the Option< &t > type
let third = v6.get(2);

// Use match to get the value
match third {
  Option: :Some(num) => println!(The third member is :{}, num), / / 3
  // If the index exceeds the array length, no error is reported, and None is returned
  Option: :None= >println!("There is no such member."),}Copy the code

Get the number of array members:

v6.len() / / 5
Copy the code

Dynamic also obeys ownership rules, mutable references cannot coexist with immutable references:

let mut v6 = vec![1.2.3.4.5];

// Immutable reference to an array
let first = &v6[0];

// Try to change the first member
v6[0] = 1; The first variable has an immutable reference to the array

// Try to add a member
v6.push(6); // Error, same problem
Copy the code

The first member is referenced by the first member, and the push member is added by the first member. Why does it not compile?

In fact, the elements in a dynamic array are stored consecutively, and there may not be enough space to put all the elements down next to each other after inserting new elements, which requires allocating new memory space and moving the old elements to the new space. The reference to the first element may point to the freed memory because of the insert behavior.

Iterate over the values in a dynamic array

Use the for loop to iterate over immutable array references:

let v7 = vec![1.2.3];
for i in &v7 {
  println!("{}", i);
  / / 1
  / / 2
  / / 3
}
println!("{}", v7); / / [1, 2, 3]
Copy the code

If you need to change a member during traversal, you need to use mutable references:

let mut v8 = vec![1.2.3];
for i in &mut v8 {
  // Note that the asterisk represents "dereference", which is used to get the original address of the member, as described later
  *i += 50;
}
println!("{:? }", v8); / / [51, 52, 53]
Copy the code

Use enumerations to store different types of values in an array

The members of dynamic arrays are all of the same type. When we need to store different types of elements in dynamic arrays, we can define and use enumerations to deal with this situation, because all variations in enumerations are defined for the same enumeration type:

// Contains three types of enumerations
#[derive(Debug)]
enum Item {
  Int(i32),
  Float(f64),
  Text(String),}/ / way
let mut v9: Vec<Item> = Vec::new();
v9.push(Item::Int(1));
v9.push(Item::Float(1.1));
v9.push(Item::Text(String::from("abc")));

2 / / way
let v10 = vec![
  Item::Int(1),
  Item::Float(1.1),
  Item::Text(String::from("abc")),];println!("{:? }", v9); / / [Int (1), Float (1.1), Text (" ABC ")]
println!("{:? }", v10); / / [Int (1), Float (1.1), Text (" ABC ")]
Copy the code

This chapter only briefly introduces the use of Vec, including the use of push to add members at the end of the array, use get to obtain the specified index of the member, in fact, there are many array operation methods, for example: POP can delete the end of the member, details can go to the official document for further study.