Rust Learning Guide
Rust programming guide organized by category
π Basics
Ownership & Borrowing β How Rust Manages Memory Without GC
The core rules that guarantee memory safety at compile time
Rust's ownership system guarantees memory safety without GC. One owner per value; when borrowing, either multiple read-only or one mutable reference allowed.
Lifetimes β How Rust's Compiler Tracks Reference Validity
Understanding 'a once and for all
Lifetimes are annotations that tell the compiler how long references are valid. Usually elided, but must be explicit when multiple references interact.
Pattern Matching β Branching with match and if let
A superior alternative to switch/case, core Rust expression style
Rust's match destructures values while branching. Exhaustive compiler enforcement guarantees no missing cases.
Result and the ? Operator β Rust Error Handling Patterns
Handling errors as types without try-catch
Rust has no exceptions. Instead, Result<T, E> explicitly represents success/failure, and the ? operator propagates errors concisely.
𧬠Type System
Traits & Generics β Polymorphism in Rust
Rust's abstraction tool: interfaces + generics combined
Traits are like Java interfaces but more powerful. Combined with generics, they enable zero-cost abstraction via compile-time monomorphization.
Enum, Option, Result β Algebraic Data Types in Rust
A type system that creates a null-free world
Rust has no null. Option<T> represents absence, Result<T, E> represents failure β as types. Possible because enums can carry data.
Box, Rc, Arc, RefCell β Smart Pointer Guide
Tools for flexibly working around ownership rules
Some patterns (recursive types, shared ownership, interior mutability) can't be solved by ownership rules alone. Smart pointers fill this gap.
β‘ Concurrency
Threads & Channels β Ownership-Based Concurrency
"Don't communicate by sharing memory; share memory by communicating"
Rust's ownership system blocks data races at compile time. std::thread spawns OS threads; mpsc channels or Arc<Mutex> share data.
async/await β Asynchronous Programming in Rust
Future trait-based async model with runtime freedom
Rust's async/await is a zero-cost abstraction where the compiler transforms Future traits into state machines. Runtime (tokio, async-std) is user's choice.
π§ Practical Patterns
What You Can Build with Rust β Project Roadmap from Beginner to Advanced
When you have no idea what to build after Hello World
Learned Rust syntax but don't know what to build? Projects organized by difficulty β from CLI tools to web servers to game engines.
Building CLI Tools with Rust
Practical command-line tools with clap + serde
Rust excels at CLI tool development. Single binary compilation, fast startup, and a solid clap/serde ecosystem.
Rust β WASM β Running Rust in the Browser
Calling Rust from JS with wasm-pack + wasm-bindgen
Compiled to WASM target, Rust runs at near-native speed in browsers. wasm-bindgen auto-handles JS β Rust type conversion.
FFI β Calling C Libraries from Rust
Practical use of extern "C", bindgen, and unsafe
Rust is directly compatible with the C ABI. Declare C functions in extern "C" blocks and call them in unsafe. VOICEVOX Engine calling Core via ctypes is the reverse of this pattern (Rust β C ABI exposure).
π Rust for Rubyists
Variables & Immutability β Why Ruby's Free Reassignment Disappears
let, mut, shadowing, const β side-by-side with Ruby variables
In Ruby, variables can be reassigned anytime. Rust defaults to immutable. Comparing mut, shadowing, and const with Ruby code.
Type System β What You Gain by Giving Up Dynamic Typing
Ruby duck typing vs Rust static type inference
Ruby uses duck typing. "If it quacks, it's a duck." Rust determines all types at compile time. Inference is powerful enough that you rarely annotate, but once set, types never change.
Functions & Methods β What Changes When def Becomes fn
Return types, semicolons, and the familiar "last expression is the return" rule
Ruby def β Rust fn. Argument types and return types must be explicit, and a single semicolon determines whether something is returned. Otherwise, surprisingly similar to Ruby.
Structs & impl β Ruby's class Splits Into Two Pieces in Rust
struct for data, impl for methods, trait for polymorphism
Ruby class bundles data and methods in one place. Rust separates struct (data) and impl (methods), using traits instead of inheritance for shared behavior.
Enums & Pattern Matching β A Powerful Evolution of Symbol and case/when
Rust enums can carry data β a concept Ruby doesn't have
Rust enums β the equivalent of Ruby Symbols or constant groups β can carry data in each variant. match is an enhanced case/when that requires handling every case.
Option<T> β Surviving in a World Without nil
How Ruby's nil and &. operator translate to Rust
Ruby nil shows up anywhere. Rust has no nil. If a value might not exist, use Option<T> β the compiler forces you to handle None.
Result & Error Handling β What Fills the begin/rescue Void
Rust handles errors as return values instead of exceptions
Ruby throws exceptions and catches with rescue. Rust has no exceptions. Instead, it returns Result<T, E> and propagates errors with the ? operator.
Iterators & Closures β Where Rubyists Feel Most at Home
select/map/reduce just became filter/map/fold
Ruby Enumerable methods exist almost identically in Rust. Names differ slightly, chaining patterns are the same. The fastest adaptation area for Rubyists.
String vs &str β The Two Faces of Strings Ruby Doesn't Have
The difference between owned and borrowed strings
Ruby has one String. Rust has two: String (owned) and &str (borrowed). Confusing at first, but it connects to the core ownership concept.
Collections β When Array and Hash Become Vec and HashMap
Arrays and hashmaps in a type-fixed world
Ruby Array and Hash become Vec<T> and HashMap<K, V> in Rust. The biggest difference: they hold only one type.
Ownership β Doing What Ruby's GC Did for You
The core Rust concept Rubyists struggle with most
In Ruby, GC handles memory cleanup. In Rust, ownership rules replace GC. The core concept: moving a value makes the original disappear.
Cargo β Bundler + Rake Combined Into One
Gemfile β Cargo.toml, bundle exec β cargo run
Ruby uses Bundler (dependencies) and Rake (build/tasks) separately. Rust does everything with Cargo: project creation, build, test, dependency management, publishing.