rusty-days icon indicating copy to clipboard operation
rusty-days copied to clipboard

πŸŽ“ My journey from JavaScript to Rust

Rusty Days

My journey from JavaScript to Rust

Rust (aka RustLang) is a language for performance, reliability, and productivity source

Resources Used:

β€’Β πŸ‘‘ Rustlings

Cheat-Sheet

YouTube

Books


βœ… Cool Projects using Rust
  • https://github.com/egoist/dum
  • https://leerob.io/blog/rust
🎁 Projects I might go make one-day


Projects Completed

  • Brainf**k compiler


Variables

  • The two options are let and const
  • Unlike JavaScript, both are immutable in Rust.

let

  • The most common
  • Write as snake_case

const

  • Requires explicit typing at initialization const a:char = 'a'
  • Cannot be marked mut
  • Write as SCREAMING_SNAKE_CASE

Types

Array-like

If length is dynamic, you must use vector, otherwise arrays and tuples are more optimized

Vectors

The most flexible option

let mut v = vec![0];
println!("element at index {} is {}", 0, vec[0]);

Arrays

Fixed length at compile-time - Like Tuples except all elements must be of same type

let a: [i32; 5] = [1, 2, 3, 4, 5];


let months = ["January", "February", "March", "April", "May", "June", "July",
              "August", "September", "October", "November", "December"];

// these two are the same
let a = [3, 3, 3, 3, 3];
let a = [3; 5];

let first = a[0];
let second = a[1];

Tuples

Fixed Length at compile-time - Not just two elements like some langauges do

  • Accessing tuple values is done with .
let long_tuple = (1u8, 2u16, 3u32, 4u64,
                      -1i8, -2i16, -3i32, -4i64,
                      0.1f32, 0.2f64,
                      'a', true);

// Values can be extracted from the tuple using tuple indexing
println!("long tuple first value: {}", long_tuple.0);
println!("long tuple second value: {}", long_tuple.1);
  • Long tuples cannot be printed
// long Tuples cannot be printed
// let too_long_tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
// println!("too long tuple: {:?}", too_long_tuple);
// TODO ^ Uncomment the above 2 lines to see the compiler error

Functions

  • Functions do not need to say return
fn reverse(pair: (i32, bool)) -> (bool, i32) {
    // `let` can be used to bind the members of a tuple to variables
    let (integer, boolean) = pair;

    (boolean, integer)
}

String like

We have chars and two types of strings

Char

Wrapped in '. Length 1

const A:char = 'a';

Primitive String

Immutable and fixed-length

let hello = "hello";

String

Wrapped in ". Growable

let mut hello = String::from("hello");
hello.push('W');
hello.push_str("orld!");

Struct

Organize complex data types. Looks kinda like a class

struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let origin = Point {x: 0, y: 0};
    println!("The origin is at ({}, {})", origin.x, origin.y);

    let origin2 = Point {
        x: 99,
        ..origin
    };
}

Tuple Scruct

A hybrid between a struct and a tuple

  • Tuple structs have a name but their fields don't
struct Color(i32, i32, i32);
let dark = Color(20,20,20);

Errors

  • Many functions in rust return Result<OK_TYPE_HERE, ERR_TYPE_HERE> - This allows the dev to handle the Ok and the Err case

Non-Recoverable errors (panic)

Want to "throw an error" that is not recoverable?

panic!("crash and burn");
let v = vec![1, 2, 3];
// index is out of range, so this will also panic
v[99];

Recoverable Errors (Result)

  • Most errors aren’t serious enough to panic. Prefer Result instead of panic

  • Short ways (auto-calls panic)

// does not allow for descriptive errors
let f = File::open("hello.txt").unwrap();
let f = File::open("hello.txt").expect("Failed to open hello.txt");
  • Best way (allows the parent to handle error AND is terse)
use std::fs::File;
use std::io;
use std::io::Read;

fn read_username_from_file() -> Result<String, io::Error> {
    // notice the "?"
    let mut f = File::open("hello.txt")?;
    let mut s = String::new();
    // notice the "?"
    f.read_to_string(&mut s)?;
    Ok(s)
}
  • Longest way (and safest way)
use std::fs::File;

fn main() {
    let f = File::open("hello.txt");

    let f = match f {
        Ok(file) => file,
        Err(error) => panic!("Problem opening the file: {:?}", error),
    };
}

Etc.

Semicolons mean a lot

Everything in rust is either a statement or an expression

  • Statements do not return values
fn main() {
    // this is a statement
    let a = 1;

    // this will error
    // the statement `let y = 6` does not return anything
    let x = (let y = 6);
}
  • This program is valid. Add a semi to x+1 and not-so!
fn main() {
    let y = {
        let x = 3;
        // notice the lack of `;`
        // this is a valid expression
        x + 1
    };

    println!("The value of y is: {}", y);
}