Rust Quick-Reference Notes
Rust: Language Overview
- Systems-language aiming for speed, reliability, memory-safety without GC
- Combines low-level control with high-level ergonomics
- Compiler enforces safety (e.g., data races, dangling refs) at compile-time
Target Audiences
- Teams needing safe concurrent code
- Students learning systems concepts
- Companies (CLI tools ➜ browser engines)
- OSS contributors to tooling/ecosystem
- Users who demand speed & long-term stability
- Cargo: build, dependency & project manager (
cargo new|build|run|check|update --release) - rustc: standalone compiler (rarely used directly for real projects)
- rustfmt: code formatter for style consistency
- rust-analyzer / RLS: IDE integration
Installation Highlights
- Use
rustup (multi-platform installer & version manager) - Verify with
rustc --version - Update:
rustup update; uninstall: rustup self uninstall - Local docs:
rustup doc
First Program Workflow
- Create dir ➜
main.rs - Compile:
rustc main.rs; run: ./main - Anatomy:
fn main(){ … }, println! macro, semicolons end statements
Cargo Project Layout
cargo new hello_cargo → Cargo.toml, src/main.rs, .gitignore- Build:
cargo build; executable in target/debug - Run:
cargo run (build + execute) - Lint-only:
cargo check - Release build:
cargo build --release → target/release
Guessing Game (Chap 2) – Concepts Preview
use rand::Rng; external crate via Cargo.toml- I/O:
use std::io;, stdin().read_line(&mut String) - Shadowing & parsing:
let guess: u32 = guess.trim().parse()?; - Pattern matching:
match guess.cmp(&secret){ … } - Looping:
loop { … break; } - Error handling shortcut:
.expect("msg")
Variables & Mutability
- Immutable by default:
let x = 5; - Mutable:
let mut x = 5; x = 6; - Constants:
const MAX_POINTS: u32 = 100_000; (type annotation mandatory) - Shadowing: reuse name → new binding
let x = x + 1;
Data Types (Scalar)
- Integers:
i8…i128, u8…u128, isize/usize (arch-dependent) - Floats:
f32, f64 (default) - Booleans:
bool - Characters:
char (4-byte Unicode scalar)
Data Types (Compound)
- Tuple: fixed size, e.g.,
let tup:(i32,f64,u8) = (500,6.4,1); ➜ destructure or index .0 - Array: fixed length
[T;N], stack-allocated, e.g., [1,2,3]; access a[i]; runtime bounds check
Functions
- Declared with
fn; snake_case naming - Parameters need types:
fn add(x:i32,y:i32)->i32 { x+y } - Statements vs expressions: last expression (no
;) is return value; use return for early exit
- Line:
// text; multi-line: repeat //
Control Flow
if/else if/else – condition must be boolif is expression → let num = if cond { 5 } else { 6 };- Loops:
loop { … break; continue; } (can return value via break val)- Labels:
'outer: loop { … break 'outer; } while condition { … }for item in collection { … } / for i in (1..=n).rev() {}
Ownership Basics (Chap 4)
- Rules:
- Each value has a single owner
- Ownership can be transferred (move)
- When owner goes out of scope, value is dropped (
drop called)
- Stack vs Heap:
- Stack: fixed-size, LIFO, fast push/pop
- Heap: dynamic allocation, pointer stored on stack, slower access
- Move semantics:
let s1 = String::from("hi"); let s2 = s1; → s1 invalid, ownership moved
- Deep copy via
clone() (explicit, potentially costly) - Types implementing
Copy trait (stack-only) are implicitly duplicated: integers, bool, floats, char, tuples of Copy types
Ownership & Functions
- Passing non-Copy types to functions moves ownership unless passed by reference (borrowing – detailed later)
- Function return can transfer ownership back
Key Takeaways
- Prefer immutability; opt-in mutability with
mut - Manage projects through Cargo & crates.io dependencies
- Use
match, pattern matching, and exhaustive handling - Understand move vs clone; cheap
Copy types vs heap-allocated data - Loops (
for, while, loop) and conditionals (if) are expressions