Industrial Training




What is a vector?

A vector is a single data structure which enables you to store more than one value next to each other in the memory. A vector is useful when we have a list of items such as items in a shopping cart.


Important points:
    A vector is used to store the value of the same type.
    Vector is denoted by Vec< T>.
    The Vec< T> is provided by the standard library which can hold the data of any type, where T determines the type of the vector.
    The data of the vector is allocated on the heap.
    A vector is a growable array means that the new elements can be added at the runtime.

Vec< T>: When a vector holds the specific type then it is represented in the angular brackets.


How to create a vector?


A vector can be created by using Vec::new() function. Let's look at this:


Let v : Vec< i32> = Vec::new();  

In the above declaration, v is a vector of i32 type and it is created by using Vec::new() function.


    There is another way to create the vector:

Rust provides vec! macro to create the vector and hold the values that we provide.


For example:
let v = vec![10,20,30,40,50];   

In the above declaration, vector v is created using a vector macro, i.e., vec!. In the case of vec!, Rust automatically infer the type of the vector v is Vec< i32> as the vector macro contains the integer values.


Note: If we want to repeat the initial value of the vector, then there is also another way of implementing vec!:


let v = vec![2 ; i];  

In the above declaration, vector 'v' is created using vector macro which contains the value 2 'i' times.


Accessing elements


The particular element of a vector can be accessed by using the subscript operator [].


Let's understand through an example:
fn main()  
{  
let v =vec![20,30,40,50];  
println!("first element of a vector is :{}",v[0]);  
println!("Second element of a vector is :{}",v[1]);  
println!("Third element of a vector is :{}",v[2]);  
println!("Fourth element of a vector is :{}",v[3]);  
}  

Output:
first element of a vector is :20
Second element of a vector is :30
Third element of a vector is :40
Fourth element of a vector is :50

    The second way of accessing the vector elements is to use the get(index) method with the index of a vector is passed as an argument and it returns the value of type Option< &t>.

Let's understand through an example:
    fn value(n:Option<&i32>)  
            {  
                match n  
                {  
                      Some(n)=>println!("Fourth element of a vector is {}",n),  
                      None=>println!("None"),  
                 }  
}  
fn main()  
{  
let v =vec![20,30,40,50];  
let a: Option< &i32>=v.get(3);  
value(a);  
}  

Output:
Fourth element of a vector is 50

In the above example, get() method is used to access the fourth element of the vector.


Difference between [] &get() method:


When we access the nonexistent element using [] operator, then it causes the program to panic. Therefore, the program is crashed when we try to access the nonexistent element. If we try to access the element by using get() method, then it returns None without panicking.


Let's understand this through an example:
    get(index)

fn value(n:Option< &i32>)  
{  
 match n  
 {  
   Some(n)=>println!("Fourth element of a vector is {}",n),  
   None=>println!("None"),  
 }  
}  
fn main()  
{  
let v =vec![20,30,40,50];  
let a: Option< &i32>=v.get(7);  
value(a);  
}  

Output:
None

    [ ] operator

fn main()  
{  
let v =vec![20,30,40,50];  
println!("{}",v[8]);  
}  

Output:

Iterating over the values in a vector


If we want to access each element of a vector, then we can iterate over the elements of a vector rather than using the indexes to access a particular element of a vector.
We can use the 'for' loop to iterate over the mutable or immutable references.


Let's see a simple example of immutable references:
fn main()  
{  
let v =vec![20,30,40,50];  
print!("Elements of vector are :");  
for i in v  
{  
  print!("{} ",i);  
}  
            }  

Output:
Elements of vector are :20 30 40 50

Let's see a simple example of mutable references:


fn main()  
{  
let mut v =vec![20,30,40,50];  
print!("Elements of vector are :");  
for i in &mut v  
{  
*i+=20;  
  print!("{} ",i);  
}  
}  

Output:
Elements of vector are :20 30 40 50

In the above example, we are changing the value of the vector. Therefore, the vector is a mutable reference. The dereference(*) operator is used before the 'i' variable to get the value of vector v.


Updating a vector


When we create the vector, then we insert the elements into the vector by using push() method. The push() inserts the new element at the end of the vector.


Let's see a simple example:
fn main()  
{  
  let mut v=Vec::new();  
  v.push('j');  
  v.push('a');  
  v.push('v');  
  v.push('a');  
  for i in v  
  {  
    print!("{}",i);  
  }  
}  

Output:
java

In the above example, push() function is used to insert the elements into the vector at the runtime. The vector 'v' is made mutable so that we can also change the value of a vector.


Dropping a vector


When a vector goes out of the scope, then it gets autonatically dropped or freed from the memory.
Let's understand this through a simple scenario:


fn main()  
{  
   let v = !vec[30,40,50];  
   } => v is freed here as it goes out of the scope.  


In the above scenario, a vector is freed when it goes out of the scope means that all the elements present in the vector will be removed.


Using Enum to store multiple types


Vectors can store the elements of the same type, and this is a big disadvantage of a vector. Enum is a custom data type which contains the variants of the various type under the same enum name. When we want to store the elements in a vector of a different type , then we use the enum type.


Let's understand this through an example:
#[derive(Debug)]  
enum Values {  
   A(i32),  
   B(f64),   
   C(String),  
}  
  
fn main()   
{  
     let v = vec![Values::A(5),   
     Values::B(10.7),Values::C(String::from("javaTpoint"))];  
     for i in v  
    {  
       println!("{:?}",i);  
     }  
}  

Output:
A(5)
B(10.7)
C(javaTpoint)

Advantages of using enum in a vector:


    Rust knows the type of the elements of a vector at the compile time as to determine how much memory on the heap is required for each element.
    When a vector consists of elements of one or more type then the operations performed on the elements will cause the error but using an enum with the match will ensure that every possible case can be handled at the runtime.



Hi I am Pluto.