Skip to content
Learni
View all tutorials
Langages de programmation

How to Get Started with Rust: Installation and First Programs in 2026

Lire en français

Introduction

Rust is a modern, high-performance, secure-by-design systems language, perfect for ambitious beginners aiming to sidestep common bugs like memory leaks or data races. Launched in 2010 by Mozilla, it blends C++ speed with managed language safety via its unique ownership system that catches errors at compile time. In 2026, Rust leads in web development (via WebAssembly), embedded systems, and cloud computing, backed by a booming community.

This tutorial walks you through everything step by step, from installation to complex programs. Why Rust? It cuts vulnerabilities by 70% versus C/C++ (Microsoft studies), delivering reliable apps from day one. By the end, you'll have a complete, production-ready project to bookmark. Ready to conquer the 'language of the future'?

Prerequisites

  • A computer running Windows 10+, macOS 11+, or Linux (Ubuntu 20+).
  • Access to a terminal (PowerShell on Windows, Terminal on macOS/Linux).
  • Basic programming knowledge (variables, loops)—no systems experience required.
  • Disk space: 500 MB for Rust and Cargo.

Install Rust with rustup

terminal
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env
rustc --version
cargo --version

This script downloads and installs rustup, Rust's official toolchain manager, which includes the rustc compiler and Cargo package manager. Run it in your terminal—it auto-detects your OS. Verify with the version commands (expect Rust 1.80+ in 2026). Pitfall: On Windows, use admin PowerShell and restart the terminal after source.

Your First Cargo Project

Cargo is Rust's all-in-one tool for building, compiling, and managing dependencies. It organizes projects with src/main.rs for code and Cargo.toml for configuration, ditching the mess of manual Makefiles.

Create a New Project

terminal
cargo new my_first_project
cd my_first_project
cargo run

cargo new generates a full skeleton: Cargo.toml, src/main.rs, and .gitignore. cargo run builds and runs in one go, printing 'Hello, world!'. It's faster than manual rustc and handles optimizations. Pitfall: Don't forget cd to enter the project folder.

Custom Hello World

src/main.rs
fn main() {
    println!("Hello, Rust in 2026!");
    println!("Your first program works.");
}

Replace the default code in src/main.rs. fn main() is the entry point; println! is a macro (note the !) for formatted output. Rerun with cargo run. Analogy: Like console.log in JS, but statically typed and natively optimized. Pitfall: Macros aren't functions—no named arguments.

Variables and Mutability

Immutability by default: Rust requires let x = 5; (immutable) to prevent concurrency issues. Add mut to modify: let mut y = 10; y += 1;. Types can be inferred or explicit: let age: u32 = 30;.

Working with Variables and Types

src/main.rs
fn main() {
    let name = "Alice"; // Immutable by default
    println!("Hello, {}!", name);

    let mut counter = 0u32;
    counter += 1;
    println!("Counter: {}", counter);

    let pi: f64 = 3.14159;
    println!("Pi ≈ {}", pi);
}

This code shows type inference (u32 for unsigned integer) and mut for changes. {} is a placeholder in println!. Run cargo run to test. Analogy: JS consts with extra safety. Pitfall: Avoid unnecessary mut—the compiler flags risky designs.

Functions and Control Flow

Functions return their last expression implicitly (no trailing ;). if is an expression, not just a statement. Use powerful loop, while, and iterator-based for loops.

Defining Functions and Loops

src/main.rs
fn greet(name: &str) -> String {
    format!("Hello, {}!", name)
}

fn main() {
    let message = greet("Bob");
    println!("{}", message);

    let mut i = 0;
    loop {
        i += 1;
        if i > 3 { break; }
        println!("Iteration {}", i);
    }

    for num in 1..=3 {
        println!("Number: {}", num);
    }
}

greet takes a &str (string slice) and returns a String with format!. Infinite loop breaks early. for iterates over inclusive range 1..=3. cargo run builds it all. Analogy: JS arrow functions with strict types. Pitfall: Skip ; on a function's last line—it returns that value!

Introduction to Ownership

src/main.rs
fn main() {
    let s1 = String::from("hello");
    let s2 = s1; // Move: s1 is invalidated
    // println!("s1: {}", s1); // Compile error!
    println!("s2: {}", s2);

    let x = 5;
    let y = x; // Copy for primitives
    println!("x: {}, y: {}", x, y);
}

fn take_ownership(s: String) { // Takes ownership
    println!("Took: {}", s);
}

fn borrow(s: &String) -> usize { // Borrows
    s.len()
}

Rust manages memory with ownership: String moves to s2, invalidating s1. Primitives like i32 copy. &String borrows without moving. Try take_ownership(String::from("test")); or borrow(&s2). Major pitfall: Forgetting & triggers unexpected moves—the compiler prevents disasters.

Structs and Methods

Structs group data; impl adds methods. Like lightweight classes without inheritance.

Creating Structs and Methods

src/main.rs
struct Person {
    name: String,
    age: u32,
}

impl Person {
    fn new(name: String, age: u32) -> Person {
        Person { name, age }
    }

    fn greet(&self) -> String {
        format!("I'm {} and I'm {} years old.", self.name, self.age)
    }
}

fn main() {
    let alice = Person::new(String::from("Alice"), 30);
    println!("{}", alice.greet());
}

struct defines the type; impl adds methods. &self borrows the instance. new is a constructor. Test with cargo run. Analogy: JS objects with safe auto-cleanup. Pitfall: self without & moves the instance—use &mut self for mutations.

Best Practices

  • Always run cargo fmt and cargo clippy: Auto-format and lint for idiomatic code.
  • Prefer & references over clones for performance; Rust optimizes borrows.
  • Use Result early for error handling without panics.
  • Test with cargo test: Unit tests for every public function.
  • Update Rust regularly: rustup update weekly for the latest stable features.

Common Errors to Avoid

  • Forgetting mut: let x = 5; x += 1; fails—add mut or rethink.
  • Move/copy confusion: Don't move reusable data; use clone() or &.
  • Unnecessary panics: Skip unwrap() in production; use match or ? operator.
  • Ignoring borrow checker errors: Read them—they build safe code, not hacks.

Next Steps

Dive into traits (interfaces), modules, and async with the official Rust Book. Explore WebAssembly for web or Tokio for servers.

Check out our Learni Rust courses: from beginner to systems expert. Join r/rust and contribute on GitHub!