A Quick Introduction to Rust
Rust is a systems programming language focused on three goals: speed, safety, and concurrency. Unlike many languages, Rust gives you the performance of C or C++ while preventing entire classes of bugs like null pointer dereferences and data races at compile time. This guide walks you through the core concepts you need to get started.
Installing and Running Rust
The easiest way to install Rust is through Rustup, the official Rust toolchain installer. Run the following in your terminal:
After installation, Rust projects are managed with Cargo — Rust's build system and package manager. To create a new project:
Cargo creates a project folder with a Cargo.toml config file and a src/main.rs source file. The cargo run command compiles and runs your program in one step.
Hello, World!
Every Rust program starts with a main function. Here's the classic Hello World:
fn main()is the entry point of every Rust program.println!is a macro (notice the!) that prints a line to the console. Macros in Rust look like functions but generate code at compile time.
Variables and Mutability
Variables in Rust are declared with the let keyword. By default, they are immutable — once set, their value cannot change.
Variable Shadowing
Rust also allows shadowing — declaring a new variable with the same name, which replaces the previous one:
Data Types
Primitive Types
- Integers:
i32,u64, etc. (signed and unsigned) - Floats:
f32,f64 - Boolean:
bool—trueorfalse - Character:
char— a single Unicode character, e.g.'A'
Compound Types
Tuples group values of different types. Arrays hold multiple values of the same type with a fixed length.
Control Flow
If / Else
Loops
Rust has three kinds of loops:
Functions
Functions are defined with fn. Parameters must have type annotations. The return type is specified with ->. In Rust, the last expression in a function is implicitly returned (no return keyword needed).
Closures
Closures are anonymous functions you can store in a variable or pass as arguments. They can capture variables from the surrounding scope.
The |x| syntax defines the parameter list, followed by the function body. Closures are commonly used with iterators and higher-order functions.
Ownership
Ownership is the most unique feature of Rust and the foundation of its memory safety guarantees — with no garbage collector needed.
This prevents double-free errors and dangling pointers at compile time, not at runtime.
Borrowing and References
Instead of moving ownership, you can borrow a value using references. References let you use a value without taking ownership of it.
By default, references are immutable. Use &mut for a mutable reference, but note: you can only have one mutable reference to a value at a time.
Structs
Structs let you define custom data types by grouping related fields together.
Enums
Enums define a type that can be one of several named variants. They are much more powerful in Rust than in many other languages — variants can carry data.
Pattern Matching
The match statement lets you compare a value against a series of patterns and run code based on which pattern matches. Every possible case must be handled.
Error Handling
Rust uses two special enum types instead of exceptions:
Option<T>— a value that may or may not exist (Some(value)orNone)Result<T, E>— an operation that can succeed (Ok(value)) or fail (Err(error))
You can also use the ? operator to propagate errors up the call stack cleanly, making error handling concise and explicit.
Modules and Project Structure
Rust organises code into modules using the mod keyword. Modules let you group related code, control visibility with pub, and keep large projects manageable.
In larger projects, modules map to files and folders. Cargo manages the project layout: source code lives in src/, dependencies are declared in Cargo.toml, and external libraries (called crates) are downloaded automatically from crates.io.