Café & Tapioca

First steps into Rust

Why I’m learning Rust?

Basically, I was planning on studying compilers, interpreters and how programming languages work on the low level part.

I tought that Rust was a good choice because it has large and active open source community, and it’s simpler than C and C++. I had sometime in last year learning C, was a pain in the ass, but I recognize the impact that it had in my understanding of how a computer memory works on the low level.

  1. Data Types;
  2. Functions;
  3. Variables & Mutability

Rust has a pretty interesting approach to variables, unlike C, Rust don’t let all variables be mutable. In a deeper level it offers more memory safe code, leading to lesser bugs on runtime.

Guessing game:

use std::io;
use std::cmp::Ordering;
use rand::Rng;

fn main() {

    // rust uses snake case as default
    println!("Secret number game!");
    let secret_number = rand::thread_rng().gen_range(1..=100);

    loop {
        let mut guess = String::new();
        println!("The secret number is: {secret_number}");
        println!("Type a number:");

        io::stdin()
            .read_line(&mut guess)
            .expect("Failed to read the line!");

        // match is basically a switch case
        // in this case i'm using him to handle exceptions
        // just like on the line 32

        // the parse method returns a **enum** 
        // it can be "Ok" or "Err", using the method 
        // match i can handle the excpetion in the case of either are returned 
        // "Err(_)" is basically a catch all

        let guess: u32 = match guess.trim().parse() {
            Ok(num) => num,
            Err(_) => continue,
        }; 

        match guess.cmp(&secret_number) {
            Ordering::Less => println!("Too small!"),
            Ordering::Greater => println!("Too big!"),
            Ordering::Equal => {
                println!("You win!");
                break;
            },
        }
    }
}

Learning how variables work:

fn main() {

    // incorrect way to re-declare variables:
    // x = x (only works for mutable variables)
    let x = 6;
    println!("x is {x}");

    // shadowing variables
    // I can also do let x = x * 5!!
    let x = 5;
    println!("x is {x}");

    // constants are **always** immutable, unlike variables.
    const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3;

    // inner scope and shadowing variables:
    let x = x + 1;

    {
        // this is an inner scope
        let x = x * 2;
        println!("x is {x}");
    }

    // the main difference between using shadowing and mut
    // is that mutable variables can be changed at any time,
    // while regular variables return to being immutable after modifications.
    // basically, we are creating a new variable but with the same name.
    println!("x is {x}");

    let spaces = "   ";
    let spaces = spaces.len();
    println!("spaces len is {spaces}");

    // incorrect way to re-declare variables:
    // let mut spaces_mut = "   ";
    // spaces_mut = spaces_mut.len();
    //
    // **compilation error, because it is not possible to mutate the variable type.**
    // this is only possible with regular variables because they are being
    // re-created in every re-declaration.
    
    // I need to define the type beforehand
    // let guess = "42".parse().expect("Failed to parse!");

    let guess: u32 = "42".parse().expect("Failed to parse!");
}

Array study:

fn main() {
    let mut counter: u32 = 0;

    let result = loop {
        counter += 1;

        if counter == 10 {
            break counter;
        } 
    };

    println!("result is {result}");

    let mut number: u32 = 3;
    println!("number is {number}");

    while number != 0 {
        number -= 1
    }
    println!("number has reached {number}");

    while number < 10 {
        number += 1;
    }
    println!("number has reached {number}");

    let mut index: usize = 0;
    let arr: [u32; 5] = [0, 1, 2, 3, 4];

    while index < 5 {
        println!("element is {}", arr[index]);
        index += 1;
    }

    // instead of looping with a size of 5, which can cause errors,
    // I can loop directly over the collection `arr`, as follows:

    println!("\n");
    for element in arr {
        println!("element is {element}");
    }

    println!("\n");

    for element in (1..4).rev() {
        println!("element is {element}");
    }
}

thinking_monke.jpg
today was a very productive day, I studied for 2.5 hours
#rust