beginner · rust
Intro to Rust
An introduction to Rust covering syntax, ownership, type safety, error handling, collections, traits, concurrency, and modular program design. Learners develop the reasoning skills needed to write reliable and maintainable Rust code.
What you could build
- A command-line text analyzer
- A type-safe configuration parser
- A concurrent file processing utility
- A terminal-based task tracker
- A reusable Rust library for structured data validation
You pick the project at the start — these are examples, not a fixed list.
What you'll be able to do
- Trace ownership transfers, moves, copies, drops, and borrows to determine whether Rust code is valid.
- Choose and use structs, enums, Option, Result, custom errors, and the question-mark operator to model and handle program outcomes.
- Select appropriate collections and iterator ownership modes, then predict the types and ownership effects of map, filter, and collect.
- Define traits and trait bounds, and reason about thread safety using move closures, channels, Send, Sync, Mutex, and Arc.
- Resolve Rust module paths, visibility, imports, re-exports, crates, packages, and file-based module hierarchies.
Who this is for
This course is for learners with some programming experience who want a structured introduction to Rust's syntax, ownership model, type system, error handling, concurrency, and module system. It fits people aiming to read, reason about, and write reliable Rust code without treating compiler errors as guesswork.
What you should already know
- Basic programming experience with variables, functions, conditional logic, and loops.
- Comfort reading short code examples and reasoning about values and control flow.
- A Rust toolchain and Cargo installation, or access to an environment where Rust code can be compiled.
How a lesson actually goes
let count = 1; count = 2;. Before we change the code, what do you predict will happen?count changes to 2 because it was declared with let. Maybe Rust only needs a type annotation to allow reassignment.let creates an immutable binding unless you add mut; a type annotation does not change that. The compiler rejects the assignment because the binding's mutability is part of how the program controls state.let mut count = 1; if I want the assignment to work. Is the value itself mutable, or is the binding mutable?let mut count = 1; permits that binding to be assigned a new value. We will next distinguish reassignment from shadowing, where a new let binding replaces the name while creating a separate binding with its own type and mutability.Written from this course's first lesson to show the format — not a recording of a real session.
Course content
marks each module's capstone lesson.
01Rust Foundations12 lessons
Establish the core language concepts needed to read and write basic Rust programs. Learners progress from variables and types through functions, control flow, ownership, and borrowing, then synthesize these ideas to reason about Rust code.
Course Introduction
Welcome and orientation: an overview of Rust's syntax, ownership model, type safety, error handling, collections, traits, concurrency, and modular design. The course develops the reasoning skills needed to write reliable and maintainable Rust code.
Variables and Mutability
Rust bindings are immutable by default, and the mut keyword explicitly permits reassignment. This lesson distinguishes declaring, initializing, and updating variables.
Scalar Types
Scalar types represent single values and include signed and unsigned integers, floating-point numbers, booleans, and characters. Rust's type rules and numeric operations determine which values and conversions are valid.
Tuples
Tuples group a fixed number of values that may have different types. Their positional structure supports direct element access and pattern-based destructuring.
Arrays
Arrays store multiple values of the same type with a length known at compile time. Indexing provides element access, while the array type records both its element type and size.
Functions
Functions organize behavior behind explicit interfaces. Rust requires parameter and return types where appropriate, and the final expression can provide a function's return value.
Expressions
Expressions evaluate to values, while statements perform actions without being values in the same way. Understanding this distinction explains semicolons, block values, and concise Rust function bodies.
Conditional Expressions
Conditional expressions choose behavior based on Boolean conditions and can produce values. Rust requires compatible branch types when a conditional is used as an expression.
Loops
Rust provides several loop forms for unconditional repetition, condition-controlled repetition, and iteration over values. Break and continue alter loop execution, and loop can return a value.
Ownership
Ownership gives each value a managing binding and enables memory safety without a garbage collector. Moves, copies, scopes, and automatic dropping determine when values remain usable.
Borrowing
Borrowing permits access to a value without transferring ownership. Shared and mutable references support different access patterns, and Rust's borrowing rules prevent conflicting use.
Foundations Synthesis
This assessment integrates the foundational language model developed throughout the module. Learners reason about how values are declared, transformed, passed, repeated over, moved, and borrowed in a coherent Rust program.
02Memory Semantics10 lessons
Deepen understanding of Rust's ownership model by connecting values to stack and heap memory, distinguishing owned strings from borrowed slices, analyzing copy and clone behavior, using smart pointers, and reasoning about reference lifetimes.
Memory Layout
Learners distinguish stack storage from heap storage and relate allocation, deallocation, and ownership to the lifetime of a value.
String
Learners analyze String as an owned, growable, heap-allocated collection of UTF-8 bytes and trace how its ownership changes when it is assigned or passed.
String Slices
Learners interpret &str as a borrowed view into string data and determine when a slice remains valid based on the lifetime of its source.
Copy Semantics
Learners identify types that implement Copy and trace how implicit bitwise copies affect the continued usability of bindings.
Clone Semantics
Learners distinguish explicit cloning from implicit copying and reason about the additional allocation or work that cloning may perform for heap-owning values.
Box
Learners analyze Box<T> as an owning pointer that allocates a value on the heap while maintaining a single owner and automatic cleanup.
Reference Counting
Learners trace reference counts as Rc values are cloned and dropped, identifying how shared ownership changes cleanup behavior.
Interior Mutability
Learners distinguish compile-time borrowing from interior mutability and predict when RefCell permits access, panics, or violates an active borrow rule.
Lifetime Annotations
Learners interpret lifetime parameters in functions and structs as constraints relating references, rather than as instructions that extend how long data lives.
Ownership and Memory Synthesis
Learners synthesize the module's memory model to determine which values are valid, when data is allocated and released, how aliases behave, and why the compiler or runtime accepts or rejects each access.
03Types and Errors10 lessons
Model related data with structs and enums, use pattern matching to handle alternative cases, and distinguish recoverable errors from unrecoverable failures. Learners apply Option and Result, propagate errors with the question-mark operator, and define error types that make failure behavior explicit.
Structs
Structs group related values under named fields and create a descriptive type for that data. Learners examine struct definitions, construction, field access, and field mutation.
Enums
Enums model values that can be one of several named variants, with each variant optionally carrying different data. Learners determine which variant a value contains and how its associated data is represented.
Pattern Matching
The match expression compares a value against patterns and selects the corresponding expression. Learners use exhaustive arms, wildcard patterns, and bindings to reason about control flow and result types.
Option
Option<T> makes missing values explicit through the Some(T) and None variants instead of using null references. Learners inspect and transform optional values with matching and common Option operations.
Result
Result<T, E> models an operation that can produce a value of type T or an error of type E. Learners distinguish successful outcomes from failures and use matching to handle each case explicitly.
Panics
A panic stops ordinary execution when a condition cannot be safely continued, while a Result communicates failure to the caller for explicit handling. Learners identify panic sources and reason about when each failure model is appropriate.
Question Mark Operator
The question-mark operator unwraps a successful Result or Option value and performs an early return for its failure case. Learners trace its control flow and verify that the surrounding function has a compatible return type.
Custom Error Types
Custom error enums give related failure conditions precise names and associated data. Learners design variants that preserve useful context and connect the error type to Result-based function signatures.
Error Propagation
Error propagation lets lower-level failures travel through function boundaries until a suitable layer can handle them. Learners reason about compatible error types, early returns, and the difference between propagating and resolving an error.
Types and Error Handling Synthesis
This synthesis assesses the complete relationship between Rust's user-defined types and its explicit error-handling model. Learners trace variant selection, pattern coverage, Result and Option behavior, panic boundaries, custom errors, and propagated failures.
04Collections and Iteration10 lessons
Learn how Rust represents growable sequences and unique or keyed data, then use iteration modes and iterator transformations to process collections safely and expressively.
Vectors
A Vec<T> stores a growable, owned sequence of values of one element type. Learners examine construction, insertion, removal, length, and capacity at a conceptual level.
Vector Access
Vector elements can be accessed with indexing or with the get method. Learners distinguish direct access that can panic from optional access that produces an Option.
Hash Maps
A HashMap associates keys with values for lookup by key rather than position. Learners reason about insertion, replacement, lookup, and the Option returned when a key is absent.
Hash Sets
A HashSet stores each value at most once and supports efficient membership-oriented operations. Learners examine insertion, removal, containment checks, and duplicate behavior.
Iterators
The Iterator trait provides a common way to traverse collections one item at a time. Learners identify the item type, the role of next, and the meaning of None at the end.
Iteration Ownership
Rust provides iteration modes that correspond to shared borrowing, mutable borrowing, and ownership transfer. Learners trace how each mode affects later use of the collection and the values produced.
Iterator Mapping
The map adapter applies a closure to every item without immediately consuming the resulting iterator. Learners predict the transformed item type and distinguish lazy transformation from collection construction.
Iterator Filtering
The filter adapter evaluates a predicate for each item and yields only items for which the predicate is true. Learners reason about retained values, predicate references, and lazy evaluation.
Collecting Iterators
The collect method consumes an iterator and gathers its items into a collection such as a Vec, HashSet, or Result. Learners use type information to explain how Rust selects the collection being built.
Collections and Iteration Synthesis
This synthesis assesses how collection choice, access behavior, iterator ownership, lazy adapters, and collection construction interact. Learners trace complete sequences of operations and justify validity, output types, and changes in ownership.
05Traits and Concurrency12 lessons
Define shared behavior with traits, constrain generic code with trait bounds, and use dynamic dispatch when appropriate. Then reason about Rust concurrency through threads, ownership transfer, channels, thread-safety traits, mutual exclusion, and shared ownership.
Traits
A trait declares methods and other behavior that a type can provide. Learners identify how traits express common capabilities without prescribing a type's internal representation.
Implementing Traits
Trait implementations provide method bodies for a type's required behavior. Learners determine which methods must be supplied and how trait methods are called on implementing values.
Trait Bounds
Trait bounds state the capabilities that generic parameters must provide. Learners connect bounds to which operations are valid inside generic code and how the compiler enforces those requirements.
Trait Objects
Trait objects such as `dyn Trait` represent values that implement a common trait when the concrete type need not be known statically. Learners distinguish dynamic dispatch from generic monomorphization and recognize when a trait can be used as a trait object.
Threads
Rust's thread API creates independently executing threads and returns handles that can be joined. Learners trace which statements may interleave and what joining guarantees about completion.
Move Closures
A `move` closure captures values by taking ownership of them, allowing the closure to outlive the scope where it was created. Learners trace how this capture mode affects ownership and thread validity.
Channels
Channels provide message-based communication between producers and consumers. Learners reason about sender and receiver ownership, message ordering, and the results returned when communication succeeds or fails.
Send
`Send` marks types whose ownership can be moved between threads safely. Learners use this property to explain why some values may enter a spawned thread while others are rejected by the compiler.
Sync
`Sync` describes whether shared references to a type can be used safely across threads. Learners distinguish `Sync` from `Send` and relate `Sync` to concurrent access through references.
Mutex
`Mutex<T>` permits access to its inner value through a lock, ensuring that only one thread accesses the protected data at a time. Learners trace lock acquisition, guard lifetimes, mutation, and poisoning results.
Arc
`Arc<T>` provides atomically reference-counted shared ownership for concurrent contexts. Learners distinguish cloning an `Arc` from cloning its inner value and trace destruction after the final owner is dropped.
Traits and Concurrency Synthesis
This synthesis assesses how traits and concurrency features interact in a complete code sample. Learners predict dispatch behavior, compiler validity, ownership transfers, message flow, synchronization, and drop behavior.
06Modules and Synthesis8 lessons
Learn how Rust organizes code into modules and crates, controls access with visibility, resolves names with paths, and exposes selected interfaces through use declarations and re-exports. Learners then synthesize these rules to reason about modular program structure and API access.
Module Declarations
A module groups related items into a namespace and establishes a hierarchy within a crate. Learners examine how `mod` declarations create and expose nested module paths.
Module Paths
Paths identify items within a module hierarchy. Learners distinguish crate-root paths from relative paths and use `crate`, `self`, and `super` to locate items.
Visibility
Rust items are private by default, and the `pub` modifier selectively expands their accessibility. Learners trace which modules and external code can access functions, types, and fields.
Use Declarations
The `use` keyword creates local bindings for items identified by paths, reducing repeated qualification. Learners determine which names a use declaration introduces and how aliases resolve naming conflicts.
Re-exports
A re-export makes an existing item available through another public path without defining a second item. Learners trace how `pub use` shapes the interface visible to code outside a module.
Crates and Packages
A crate is a compilation unit with a library or binary root, while a package is a Cargo-managed collection that may contain one or more crates. Learners connect crate roots to the starting point of a module tree.
File-Based Modules
Rust can represent a module tree across source files and directories while preserving the same namespace rules as inline modules. Learners determine which file a declaration refers to and how child modules fit into the tree.
Modular Program Synthesis
This synthesis evaluates how Rust's module-system rules interact across a complete namespace hierarchy. Learners predict which references compile, which accesses are rejected, and which paths form the intended public interface.
Questions
Do I need to know Rust before starting?
No. The course introduces Rust syntax from the beginning, then builds toward ownership, lifetimes, errors, collections, concurrency, and modular design. Basic programming experience is assumed.
How much programming experience is expected?
You should already understand common ideas such as variables, functions, conditionals, loops, and basic types. You do not need prior experience with ownership systems, generics, or concurrent programming.
Will the course explain why the borrow checker rejects code?
Yes. Ownership, borrowing, moves, copies, lifetimes, and interior mutability are treated as reasoning skills. Lessons ask you to trace validity and access rules rather than only memorize compiler fixes.
Does the course cover error handling beyond panic?
Yes. It contrasts panics with recoverable errors and covers Option, Result, the question-mark operator, custom error types, and error propagation through multiple functions.
Does it include concurrency and thread safety?
Yes. You will reason about spawned threads, move closures, channels, Send, Sync, Mutex, and Arc, including ownership and locking across thread boundaries.
Is this course focused on building one particular application?
No. The lessons focus on transferable Rust concepts and code analysis, progressing from foundations through synthesis of types, memory behavior, collections, concurrency, and module structure.
The first lesson is ten minutes away.
Free while codeset is early. You choose what you're building before the first lesson starts, and the course is taught around it.