Index

Rust

  1. Guessing Game
  2. Common Programming Concepts
    1. Variables and Mutability
    2. Data Types
    3. Function
    4. Control Flow
  3. Understanding Ownership
    1. References and Borrowing
    2. The Slice Type
  4. Using Structs
    1. An Example Program Using Structs
    2. Method Syntax
  5. Enums and Pattern Matching
    1. The match Control Flow Operator
    2. Concise Control Flow with if let
  6. Managing Growing Projects with Packages, Crates, and Modules
    1. Defining Modules to Control Scope and Privacy
    2. Paths for Referring to an Item in the Module Tree
    3. Bringing Paths into Scope with the use Keyword
    4. Separating Modules into Different Files
  7. Common Collections
    1. Storing UTF-8 Encoded Text with Strings
    2. Storing Keys with Associated Values in Hash Maps
  8. Error Handling
    1. Unrecoverable Errors with panic!
    2. Recoverable Errors with Result
  9. Generic Types, Traits, and Lifetimes
    1. Traits: Defining Shared Behavior
    2. Generics Rust by Example
      1. Functions
      2. Implementation
  10. Writing Automated Tests
  11. Object Oriented Programming
  12. Adding dependancies
  13. Option Take
  14. RefCell
  15. mem
  16. Data Structure
    1. Linked List
    2. Binary search tree
    3. N-ary Sum tree
  17. Recipe
    1. Semi colon
    2. Calling rust from python
    3. Default
    4. Crytocurrency With rust
    5. Function chaining
    6. Question Mark Operator
    7. Tests with println
    8. lib and bin
    9. Append vector to hash map
    10. Random Number
    11. uuid4
    12. uwrap and option
  18. Blockchain with Rust
  19. Near Protocol
    1. Startup code
    2. Couter
    3. Status
    4. Avrit
  20. Actix-web

Common Collections

Storing Lists of Values with Vectors

The first collection type we’ll look at is Vec<T>, also known as a vector. Vectors allow you to store more than one value in a single data structure that puts all the values next to each other in memory. Vectors can only store values of the same type. They are useful when you have a list of items, such as the lines of text in a file or the prices of items in a shopping cart.

Creating a New Vector
 let v: Vec<i32> = Vec::new();

Note that we added a type annotation here. Because we aren’t inserting any values into this vector, Rust doesn’t know what kind of elements we intend to store. This is an important point. Vectors are implemented using generics; we’ll cover how to use generics with your own types.

In more realistic code, Rust can often infer the type of value you want to store once you insert values, so you rarely need to do this type annotation. It’s more common to create a Vec<T> that has initial values, and Rust provides the vec! macro for convenience.

    let v = vec![123];


Because we’ve given initial i32 values, Rust can infer that the type of v is Vec<i32>, and the type annotation isn’t necessary. Next, we’ll look at how to modify a vector.

Updating a Vector
let mut v = Vec::new();

    v.push(5);
    v.push(6);
    v.push(7);
    v.push(8);


Dropping a Vector Drops Its Elements
    {
        let v = vec![1234];

        // do stuff with v
    } // <- v goes out of scope and is freed here


When the vector gets dropped, all of its contents are also dropped, meaning those integers it holds will be cleaned up.

Reading Elements of Vectors
Example shows both methods of accessing a value in a vector, either with indexing syntax or the get method.

    let v = vec![12345];

    let third: &i32 = &v[2];
    println!("The third element is {}", third);

    match v.get(2) {
        Some(third) => println!("The third element is {}", third),
        None => println!("There is no third element."),
    }

Output:
The third element is 3
The third element is 3

Panic!
   let v = vec![12345];

    let does_not_exist = &v[100];
    let does_not_exist = v.get(100);

Attempting to access the element at index 100 in a vector containing five elements


Panic!
    let mut v = vec![12345];

    let first = &v[0];

    v.push(6);

    println!("The first element is: {}", first);

Attempting to add an element to a vector while holding a reference to an item

Iterating over the Values in a Vector
    
    let v = vec![1003257];
    for i in &v {
        println!("{}", i);
    }


We can also iterate over mutable references to each element in a mutable vector in order to make changes to all the elements.
fn main() {
    let mut v = vec![1003257];
    for i in &mut v {
        *i += 50;
    }
}


To change the value that the mutable reference refers to, we have to use the dereference operator (*) to get to the value in i before we can use the += operator.
fn main() {
    let mut v = vec![1003257]; // [100, 32, 57]
    println!("{:?}", v);
    for i in &mut v {
        *i += 50;
    }
    println!("{:?}", v); // [150, 82, 107]
}


Using an Enum to Store Multiple Types
At the beginning of this chapter, we said that vectors can only store values that are the same type. This can be inconvenient; there are definitely use cases for needing to store a list of items of different types. Fortunately, the variants of an enum are defined under the same enum type, so when we need to store elements of a different type in a vector, we can define and use an enum!

fn main() {
    enum SpreadsheetCell {
        Int(i32),
        Float(f64),
        Text(String),
    }

    let row = vec![
        SpreadsheetCell::Int(3),
        SpreadsheetCell::Text(String::from("blue")),
        SpreadsheetCell::Float(10.12),
    ];
}