This Notion page is designed to help you dive deep into Rust—a powerful, modern programming language known for its speed, memory safety, and concurrency. This guide will walk you through all the key concepts, from basic syntax to some intermediate Topics such as Generics, Traits and lifetimes and some advance topics such as smart pointers , Declarative Macros, Procedural Macros, Concurrency and many more.
The content in this guide draws from various reliable Rust learning resources, including:
This Notion page consolidates and simplifies key concepts from these sources, making them easier to grasp while building a solid foundation in Rust.
Rust is fast, memory-safe, and allows fearless concurrency. It’s increasingly being adopted in industries ranging from system programming to web development.
| Aspect | Typescript | Python | C | Rust |
|---|---|---|---|---|
| Typing | Static | Dynamic | Static | Static |
| Memory Management | Garbage Collected | Garbage Collected | Manual (Shooting at the foot) | Manual with safety checks |
| Compilation | Transpiles to JavaScript (JIT) | Interpreted | Ahead-of-time | Ahead-of-time |
| Concurrency | Single Threaded | Multi-threaded (limited by GIL in CPython, no limit in other implementations like Jython) | Manual Thread management | Built in concurrency model |
| Use case | Web dev , server side scripting (with NodeJS) | Web dev, data analysis , scripting | Systems Programming, Embedded Systems, OS Development | Systems Programming, Web Assembly , Web servers etc. |
| Performance | Depends on the JS engine | Slower (interpreted lang) | Fast ( Low Level lang ) | Fast (Low level lang with zero cost abstractions) |
| Error Handling | Try/catch exceptions | Try/except exceptions | Return codes (No built in exception handling ) | Result and Option types for error handling. |
In Rust, every program starts execution from the main function, similar to many other languages like C, C++, and Java. The main function is the entry point of your Rust program, and it's required in every executable Rust project.
fn main(){
//Write your code here.
}
fn main() {.....}
fn keyword, followed by the function name which in this case is main and we write our function body in the curly braces.//main.rs
fn main(){
println!("Hello World"); //prints hello world with a new line on the std output.
}
println!(”Hello World”);
println! is a macro that prints the formatted text to the standard output with a new line. we will be learning macros in rust later in this guide.print!(”Hello world”) this will print the Hello world without a new line at the end.; , without this the compiler will throw an error.rustc [main.rs](<http://main.rs>) compiles the rust code../main run the executable.Cargo is Rust`s Build system and package manager, it plays a crucial role in managing dependencies , compiling code, running tests etc.
Here are some uses
Create a rust project using cargo:
$ cargo new helloworld helloworld here is a project name.
You will get something like this:
helloworld/ ├── Cargo.toml └── src └── main.rs
Here we have a main.rs file which contains the main function and a cargo.toml file which contains your projects metadata and dependencies just like a package.json file in javascript if you are from a javascript background.
[package]
name = "helloworld"
version = "0.1.0"
edition = "202X"
[dependencies]
//your dependencies
Building your project using Cargo:
cargo build this will compile your code (we can add some flags but lets keep it simple for now)Run Your Project:
Remember last time when we need to run rust code we have to compile it using the rustc compiler and then run it manually , But now cargo will do that for us we just need to run :
$ cargo run this compile and run the project.
Adding an external Crate (Dependency):
cargo add rand → rand is a crate name i want to add to my project.
if you now check your cargo.toml file it will look something like this:
[package]
name = "helloworld"
version = "0.1.0"
edition = "202X"
[dependencies]
rand = "0.8.5" //this is the crate with the version number
We can learn more about cargo like cargo workspaces , but for now this is enough for us to work with rust.
Every value in rust has a type, which determines what kind of data it can store and how it can be used. And all the types must be known at the compile time. There are a variety of built in datatypes.
These types represent a single value, There are four primary scalar types
let x : u8 = 12;
printnln!("{}",x); //12
<aside> 💡
</aside>
let is used to declare variable x.
Compound types can store multiple values into the single type. There are two primary compound types in rust.
Tuples
let data:(132,f32,char,bool) = (12,12.2,'A',false);
//we can destructure the values
let (twelve, twelve_point, letter, is_dead) = data;
println!("twelve: {}, twelve_point: {}, letter:{} is_dead:{} ",twelve, twelve_point, letter, is_dead);
let firstElm = data.0; //12
let secondElm = data.1; //12.2
Arrays
Array is a collection of values of same type store in a contiguous block of memory with a fixed length.
// [i8; 5] -> i8 is the type of the elements in the array and 5 is the size of the array
let nums: [i8;5] = [1,2,3,4,5]; //array of 5 8 bit ints
let firstElm = nums[0]; //1
let secondElm = nums[1]; //2
//Create an array of size 5 and fill it with zeros;
let zeros: [i8,5] = [0;5]; //[0,0,0,0,0]
let length_of_array = zero.len(); //5 -> lenght of the array
//MULTI DIMENSIONAL Arrays
let matrix: [[i32;3];2] = [
[1,2,3],
[4,5,6],
]
//Iteration over arrays
let numbers = [1,2,3,4,5];
for num in numbers.iter(){ //for now just ignore .iter() we will cover it later.
println!("{}",num);
}
<aside> 💡
</aside>
Ownership is one of Rust’s most distinctive features. It's a system that ensures memory safety without needing a garbage collector. In Rust, each value has a single owner, and once the owner goes out of scope, the value is dropped.
Rust has three main rules for ownership:
{
let x = String::from("Hello"); // `x` owns the String.
// Do something with `x`
} // `x` goes out of scope and the memory is freed.
Once x goes out of scope, Rust automatically frees the memory allocated for the string. You don’t need to manually de-allocate it like in C or C++.
Rust enforces single ownership by moving ownership when a variable is assigned to another.
let str1 = String::from("Hello");
let str2 = str1; // Ownership of the String moves from `str1` to `str2`.
// `str1` is now invalid.
After the move, s1 is no longer valid, and trying to use it will cause a compile-time error. However, simple types like integers implement the Copy trait, so they are copied rather than moved:
let x = 5;
let y = x; // `x` is copied to `y`, so both are valid.
println!("x: {}, y: {}", x, y);
<aside> 💡
</aside>