Introduction to Rust
What is Rust?
Rust is a systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety. Created by Mozilla and first released in 2010, it's designed to provide memory safety without using a garbage collector.
Key Features
- Memory Safety: No null pointers, no dangling pointers, no data races
- Zero-Cost Abstractions: High-level features with no runtime overhead
- Concurrency: Write concurrent code without fear
- Performance: Comparable to C and C++, 10-100x faster than Python
- Great Tooling: Cargo (package manager), rustfmt (formatter), clippy (linter)
- Helpful Compiler: Error messages that teach you
Coming from Python?
If you're a Python developer, Rust will feel different but rewarding:
- No GIL: True parallelism across CPU cores
- Compiled: Binary deployment, no Python runtime needed
- Static typing: Catch bugs at compile time instead of runtime
- No garbage collector: Deterministic memory management via ownership
- 10-100x faster: Performance comparable to C/C++
Check out Chapter 0: Python to Rust for a detailed comparison guide.
Where Rust Shines
| Use Case | Why Rust? |
|---|---|
| CLI Tools | Single binary, fast startup, cross-platform |
| Web Services | High performance, safe concurrency |
| System Programming | OS kernels, drivers, embedded systems |
| WebAssembly | Safe, fast code in the browser |
| Game Development | Performance + safety guarantees |
| Blockchain | Security-critical applications |
Installation
Linux and macOS
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Windows
Download and run rustup-init.exe
Verify Installation
rustc --version
cargo --version
You should see output like:
rustc 1.93.0 (254b59607 2026-01-19)
cargo 1.93.0 (083ac5135 2025-12-15)
Update Rust
rustup update
Your First Rust Program
Using Cargo (Recommended)
# Create a new project
cargo new hello_world
cd hello_world
# Your project structure
# hello_world/
# ├── Cargo.toml (project configuration)
# └── src/
# └── main.rs (your code)
Look at src/main.rs:
fn main() {
println!("Hello, world!");
}
Run it:
cargo run
Output:
Compiling hello_world v0.1.0 (/path/to/hello_world)
Finished dev [unoptimized + debuginfo] target(s) in 0.50s
Running `target/debug/hello_world`
Hello, world!
Manual Compilation (Without Cargo)
# Create a file
echo 'fn main() { println!("Hello!"); }' > hello.rs
# Compile
rustc hello.rs
# Run
./hello
Understanding the Basic Program
fn main() {
println!("Hello, world!");
}
Let's break this down:
| Element | Explanation |
|---|---|
fn | Keyword to define a function |
main | Special function - entry point of every Rust program |
() | Parameters (none here) |
{} | Function body |
println! | A macro (note the !) that prints to console |
"Hello, world!" | A string literal |
; | Statement terminator |
Macros vs Functions
println!with!is a macro (generates code at compile time)printlnwithout!would be a function (but doesn't exist)
Common macros:
println!()- Print with newlineprint!()- Print without newlineformat!()- Create a Stringvec![]- Create a vectorpanic!()- Terminate program with error
Cargo Basics
Cargo Commands
# Create new project (binary)
cargo new myproject
# Create new library
cargo new --lib mylib
# Build (debug mode)
cargo build
# Build (release mode - optimized)
cargo build --release
# Run the program
cargo run
# Run with arguments
cargo run -- arg1 arg2
# Check code without building (fast)
cargo check
# Run tests
cargo test
# Update dependencies
cargo update
# Format code
cargo fmt
# Lint code
cargo clippy
Project Structure
myproject/
├── Cargo.toml # Project manifest
├── Cargo.lock # Dependency lock file (generated)
├── src/
│ └── main.rs # Entry point
└── target/ # Build artifacts (generated)
└── debug/
└── myproject # Your executable
Cargo.toml
The project configuration file:
[package]
name = "myproject"
version = "0.1.0"
edition = "2024" # Rust 1.85+ supports the 2024 edition
[dependencies]
# Add external crates here
# serde = "1.0"
Note on Editions: Rust uses an "edition" system to introduce changes while maintaining backward compatibility. The 2024 edition is the latest (stabilized in Rust 1.85), but all code in this tutorial works with both 2021 and 2024 editions. If you see edition = "2021" in examples, that's still perfectly valid - you can use whichever edition you prefer.
Hello World Variations
With Variables
fn main() {
let name = "Rustacean";
println!("Hello, {}!", name);
}
With User Input
use std::io;
fn main() {
println!("What's your name?");
let mut name = String::new();
io::stdin()
.read_line(&mut name)
.expect("Failed to read line");
println!("Hello, {}!", name.trim());
}
Run it:
cargo run
# Enter your name when prompted
With Command Line Arguments
use std::env;
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() > 1 {
println!("Hello, {}!", args[1]);
} else {
println!("Hello, world!");
}
}
Run it:
cargo run -- Alice
# Output: Hello, Alice!
The Rust Compiler as Teacher
One of Rust's superpowers is its helpful compiler. Let's see it in action:
fn main() {
let x = 5;
x = 6; // Error!
println!("{}", x);
}
The compiler says:
error[E0384]: cannot assign twice to immutable variable `x`
--> src/main.rs:3:5
|
2 | let x = 5;
| -
| |
| first assignment to `x`
| help: consider making this binding mutable: `mut x`
3 | x = 6;
| ^^^^^ cannot assign twice to immutable variable
The compiler:
- Tells you exactly what's wrong
- Shows the problematic code
- Suggests a fix:
let mut x = 5;
Key Insight: In Rust, variables are immutable by default. You must explicitly make them mutable with mut.
Rust's Philosophy
Memory Safety Guarantees
Rust prevents common bugs at compile time:
| Bug Type | How Rust Prevents |
|---|---|
| Null pointer dereference | No null pointers (uses Option<T>) |
| Use after free | Ownership system |
| Double free | Ownership system |
| Buffer overflow | Bounds checking |
| Data races | Ownership + borrowing rules |
The Ownership System
This is Rust's secret sauce (covered in depth in Chapter 3):
- Each value has an owner
- Only one owner at a time
- When owner goes out of scope, value is dropped
This enables memory safety without garbage collection.
Development Workflow
# 1. Create project
cargo new myapp && cd myapp
# 2. Edit code
# (use your favorite editor)
# 3. Quick check (fastest)
cargo check
# 4. Test compile
cargo build
# 5. Run
cargo run
# 6. Add dependencies (edit Cargo.toml)
# [dependencies]
# rand = "0.8"
# 7. Build with new deps
cargo build
# 8. Before commit
cargo fmt
cargo clippy
cargo test
Setting Up Your Editor
VS Code (Recommended)
Install extensions:
- rust-analyzer - Language server (autocomplete, go to definition)
- CodeLLDB - Debugger
- Even Better TOML - For Cargo.toml
Other Editors
- Vim/Neovim: Use rust-analyzer with coc.nvim or native LSP
- Emacs: rust-mode + lsp-mode
- IntelliJ: Rust plugin
- Sublime Text: Rust Enhanced + LSP
Common First-Day Issues
Issue: "Command not found: cargo"
Solution: Restart your terminal or run:
source $HOME/.cargo/env
Issue: Slow Compilation
Solution:
# Use cargo check for quick feedback
cargo check
# Use --release only when needed
cargo build --release
Issue: Cryptic Error Messages
Solution: Read carefully - Rust errors are detailed. Look for:
- The error code (e.g., E0384)
- The suggestion (usually after "help:")
- The problematic line
Practice Exercises
Exercise 1: Hello Name
Create a program that:
- Asks for your name
- Asks for your age
- Prints "Hello, [name]! You are [age] years old."
Exercise 2: Calculator
Create a program that:
- Takes two numbers as command line arguments
- Prints their sum
Example:
cargo run -- 5 3
# Output: 5 + 3 = 8
Exercise 3: Temperature Converter
Create a program that converts Celsius to Fahrenheit.
Formula: F = C × 9/5 + 32
Key Takeaways
- Rust prioritizes safety and performance
- Cargo is your one-stop tool for building Rust projects
- The compiler is your friend - read error messages carefully
- Variables are immutable by default
- Rust has no garbage collector but guarantees memory safety
Next Steps
In the next chapter, we'll dive into Rust's type system, variables, and basic operations.
Quick Reference Card
// Create a project
cargo new myproject
// Run a program
cargo run
// Variables (immutable)
let x = 5;
// Variables (mutable)
let mut y = 10;
y = 20;
// Print to console
println!("Value: {}", x);
// Function definition
fn main() {
// code here
}