Ultimate Rust Crash Course — Short Notes

This post is a compilation of short notes from the Ultimate Rust Crash Course available on Udemy. Taught by Nathan Stocks, the course is pretty exhaustive considering that it’s only 3 hours of teaching material. I’ll recommend it to anyone who wants to get started in Rust quickly.

Introduction and Quick Start

  • Rust ensures memory safety (unlike C/C++), concurrency and speed.
  • Rust has a package manager named cargo. It is also the build system, doc generator and testing tool.
  • Variables are by default immutable.
  • Functions defined using fn keyword. Don’t need to be chronologically arranged. Macros are special functions that end with an ‘!’.
  • All functions are private by default. Add pub before fn to make a function public and available to external code files.
  • Quick start hello world app:

Basics and Datatypes

Modules and Library

  • main.rs and lib.rs are special files in root of the project. While main→ fn main() {} is the starting point of code execution, public functions in the lib file are available by default in the project as imports.
  • Standard library : std:: -- requirement --

Scalar Types

  • Digits can be separated by any number of ‘_’ underscores, which are ignored in parsing. This is to enhance the readability. 10000 = 10_000
  • Strings are UTF-8, characters are not — hence, strings do not use characters. Hence, characters are fairly useless.

Compound Types

  • Tuples are not accessed with square brackets, as in other languages to emphasize that they need not be of the same data type.
  • Maximum size of a tuple is 12 — above this tuples have limited functionality.
  • Arrays are limited to 32 elements in size. Beyond this they lose functionality.

String

  • There are 6 types of strings in Rust. 2 are commonly used.
  • str is called a string slice. Commonly used as &str — borrowed string slice.
  • A literal is always a borrowed string slice.
  • String is another type of string — this can be modified, unlike str.
  • internally, str is made up of a pointer and length. String is made up of a pointer, length and capacity.
  • Both str and String are valid UTF-8.
  • Strings can’t be referenced by position. This is to accommodate non-English languages, and to ensure constant speed of access for non-English graphemes.

Control Flow

  • loops have to be named starting with a single apostrophe. Eg. 'this
  • when for loops are written with 2 dots : 1..100 — start is inclusive, end is exclusive, when written with 2 dots and an equal size : 1..=100 — start and end are both inclusive

Ownership, References and Borrowing

Ownership

  • Each value has an owner
  • There is only one owner for a value — stack to heap pointer allows only one reference
  • Value gets dropped if owner is out of scope 2
  • the term copy is used when only stack data is being copied. When both stack and heap data are copied the term clone is used. Clone is a deep copy. No leaks or dangling pointers are possible in rust.

References and Borrowing

  • reference default to immutable, even if values being referenced are mutable. To pass a mutable reference to a mutable value, use &mut variable.
  • the ‘.’ method on a reference automatically dereferences down to the actual value. You don’t have to worry if a variable is a reference or a value.
  • You can either have one mutable reference, or any number of immutable references to a variable.

Deeper Concepts

Structs

  • all values of a struct need to be instantiated for struct declaration.
  • Rust doesn’t have Struct inheritance.

Traits

  • Similar to interfaces in other languages.
  • Traits define required behavior. Functions and methods that a struct must implement to have the trait.
  • The behavior implemented here by the trait could have directly been an associated function for the Sample trait. But we use traits because when a trait is defined, we can write generic functions which accept any value that implements the trait.
  • Copy is a special trait. If a type implements Copy, it will be copied, instead of being moved, in move situations.
  • Simple types like integers, boolean and floats implement copy.
  • If a type uses Heap, it cannot implement Copy.
  • Traits can inherit from other traits.
  • Traits can have default behavior as well.
  • Fields can’t be defined as part of traits. Traits can only be methods. The work around is to define setter and getter methods.

Collections

  • if index is out of bounds in vector, rust throws an error, doesn’t return garbage values.
  • there are a ton of methods for vectors for sorting, searching, slicing etc.
  • other collections include vecDeque — similar to queue etc.

Enums

  • enums in Rust can comprise of complex items of different datatypes.
  • when matching enums, the match must be exhaustive.
  • a single underscore can be used to match default.

Closures

  • A closure is an anonymous function that can borrow or capture some data from the scope it is nested in.
  • Closure need not have any arguments or return values.
  • by default, closure borrows values, so their are restrictions on how you can use closures with threads, as the thread from which a closure is borrowing value might end before it is called from another thread. Hence, closure also allows us to move values.
  • To avoid the consumption of passed values to a closure, use references.

Threads

  • Threading is portable in rust. Platform independent.
  • Threading is heavy, for lighter work that just needs an asynchronous approach, use async await
  • Rust provides asynchronous channels for communications between threads, these can be declared and used as follows. Sourced from rust docs.

Feel free to reach out to me to discuss any doubts that you might have. You can reach me through my website — vivekkaushal.com

Hacker | Building Enterpret | ex-Samsung, IIIT-H | vivekkaushal.com