Free course · 50 topics · about 110 hours
Rust Programming
Ask or find help in Rust Programming
Type a question or a word. You get the topics, explanations, meanings and quiz answers that cover it, and each result opens at the right place.
Try:
Your timeline: start to finish
About 16 weeks at 1 hour a day (111 study days) · 0/12 modules done
BeginnerWeeks 1–6
4 topics · 1.5 h of lessons · ~6.9 h with practice · you are here
- Types, control flow and functionsWeeks 1–3
5 topics · 2.1 h of lessons · ~9.6 h with practice
📝 Module 2 exam: Types, control flow and functions · 13 questions
- Ownership: Rust's big ideaWeeks 3–4
4 topics · 1.9 h of lessons · ~8.8 h with practice
- Borrowing, slices and lifetimesWeeks 4–6
4 topics · 2.2 h of lessons · ~10 h with practice
📝 Module 4 exam: Borrowing, slices and lifetimes · 13 questions
IntermediateWeeks 6–11
- Structs, enums and pattern matchingWeeks 6–7
4 topics · 1.8 h of lessons · ~8.5 h with practice
📝 Module 5 exam: Structs, enums and pattern matching · 13 questions
- Error handling and collectionsWeeks 7–8
5 topics · 2.3 h of lessons · ~10.3 h with practice
📝 Module 6 exam: Error handling and collections · 14 questions
- Modules, crates, traits and genericsWeeks 8–9
4 topics · 1.9 h of lessons · ~8.9 h with practice
📝 Module 7 exam: Modules, crates, traits and generics · 13 questions
- Closures, iterators and smart pointersWeeks 9–11
4 topics · 2 h of lessons · ~9.2 h with practice
📝 Module 8 exam: Closures, iterators and smart pointers · 13 questions
ExpertWeeks 11–16
- Concurrency and asyncWeeks 11–12
4 topics · 2.1 h of lessons · ~9.6 h with practice
- Testing, tooling and unsafe RustWeeks 12–13
4 topics · 1.8 h of lessons · ~8.5 h with practice
📝 Module 10 exam: Testing, tooling and unsafe Rust · 12 questions
- Real projects: CLI, web and WebAssemblyWeeks 13–15
4 topics · 2.1 h of lessons · ~9.6 h with practice
- Rust careers and interviewsWeeks 15–16
4 topics · 2 h of lessons · ~9.2 h with practice
📝 Module 12 exam: Rust careers and interviews · 10 questions
Final exam: Rust ProgrammingWeek 16
37 questions · 60 min · pass 70% for the certificate
Weeks count lessons, practice, quizzes and exams (about 110 hours in all), studying every day. Go faster or slower as you like: your place is kept on this device.
0/50 topics done
Beginner
Weeks 1–5. Install Rust, learn types, control flow and functions, then master ownership, borrowing, slices and lifetimes. After this level you can write small programs and read borrow-checker errors without fear.
1Getting started with Rust0/4 topics▼
What Rust is and why companies use it, installing it with rustup, your first program with cargo, and variables, mutability, shadowing and constants. After this module you can install Rust, create, build and run a cargo project, and store values in variables the Rust way.
- What Rust is and why learn itRust is a compiled programming language that is as fast as C and C++ but stops most memory bugs before the program ever runs. It has no garbage collector; instead, the compiler checks who owns each piece of memory. It is harder to learn than Python, but the programs it produces are fast, safe and reliable.20 min
- Installing Rust with rustupYou install Rust with rustup, the official installer and version manager. It gives you rustc (the compiler), cargo (the build tool and package manager) and the standard library. On Windows you also need the Microsoft C++ build tools; on any system, VS Code with the rust-analyzer extension is a good editor.20 min
- Your first program and cargocargo new creates a project with a Cargo.toml file and src/main.rs. Every Rust program starts in fn main. println! prints a line; the exclamation mark means it is a macro. cargo run builds and runs, cargo check only checks for errors, and cargo build --release makes a fast, optimised program.25 min
- Variables, mutability, shadowing and constantslet creates a variable, and in Rust variables cannot change unless you add mut. Shadowing means declaring a new variable with the same name, which can even change the type. const makes a constant that never changes, with a written type and an UPPER_CASE name.25 min
2Types, control flow and functions0/5 topics▼
Numbers, booleans and characters, tuples and arrays, functions and the difference between statements and expressions, if, loop, while and for, and a first interactive program that reads input. After this module you can write small Rust programs that calculate, decide, repeat and talk to the user.
- Scalar types: numbers, bool and charA scalar type holds one value. Rust has signed integers (i8 to i128), unsigned integers (u8 to u128), isize and usize, floating-point numbers (f32, f64), bool and char. Integers default to i32 and decimals to f64. Integer overflow panics in a debug build, so Rust gives you checked, wrapping and saturating methods.25 min
- Compound types: tuples and arraysA tuple groups a fixed number of values of different types, like (String name, age). An array holds a fixed number of values of the same type, like [i32; 5]. You read tuple parts with .0, .1 or by destructuring, and array items with [index]. Reading past the end of an array panics at run time.20 min
- Functions, statements and expressionsFunctions are written with fn, and every parameter needs a type. The return type comes after ->. In Rust, the last expression in a function body, written without a semicolon, is the value the function returns. Adding a semicolon by mistake turns it into a statement that returns () and causes a type error.25 min
- Control flow: if, loop, while and forif needs a real bool; Rust has no "truthy" values. Because if is an expression, it can give a value: let fee = if member { 0 } else { 50 };. Rust has three loops: loop (forever, until break, which can return a value), while (while a condition is true) and for (over a range or a collection, the most used).25 min
- Mini project: reading input from the userstd::io::stdin().read_line(&mut text) reads one line typed by the user into a String. The text includes the newline, so call trim() before parse() turns it into a number. parse can fail, so it returns a Result; match on it to handle bad input instead of crashing.30 min
3Ownership: Rust's big idea0/4 topics▼
How memory works (stack and heap), the three ownership rules, moves, Copy and Clone, and how ownership passes into and out of functions, all with pictures. After this module you can predict when a value is moved, copied or dropped, and fix "use of moved value" errors.
- Memory 101: the stack and the heapA running program keeps data in two places: the stack, which is fast and holds values of a fixed, known size, and the heap, which holds data that can grow, like text and lists. Heap memory must be freed exactly once. Mistakes here cause crashes and security holes in C, and slow garbage collection in Java; Rust solves it with ownership.30 min
- The ownership rules and movesRust has three ownership rules: each value has one owner; there is only one owner at a time; when the owner goes out of scope, the value is dropped (freed). Assigning a String to another variable moves it: the old variable can no longer be used. This is how Rust avoids double frees without a garbage collector.35 min
- Copy and CloneSmall, simple types that live only on the stack (integers, floats, bool, char, and tuples or arrays of them) implement Copy: assignment copies them and the old variable stays valid. Types that own heap data, like String and Vec, are moved instead. .clone() makes a full, deep copy on purpose, which costs time and memory.25 min
- Ownership and functionsPassing a value to a function works like assignment: a String is moved into the function and dropped when the function ends, while Copy types are copied. Returning a value moves ownership back to the caller. Passing ownership in and out all the time is clumsy, which is exactly why Rust has references (next module).25 min
4Borrowing, slices and lifetimes0/4 topics▼
References and borrowing, the borrowing rules and the borrow checker's most common errors with their fixes, string and array slices (with UTF-8 text such as Hindi), and lifetimes explained from zero. After this module you can write functions that borrow instead of taking ownership, fix the common borrow-checker errors, and read lifetime annotations.
- References and borrowingA reference (&value) lets code use a value without owning it; this is called borrowing. A shared reference &T can only read; a mutable reference &mut T can change the value. The rule: at any moment you may have many shared references OR exactly one mutable reference, and a reference can never outlive the value it points to.30 min
- The borrow checker in practiceThe borrow checker is the part of the compiler that enforces the borrowing rules. A borrow lasts only until its last use, not to the end of the block. Learn the common errors: E0382 (use after move), E0499 (two mutable borrows), E0502 (mutable borrow while a shared one is still used), E0106 (missing lifetime) and E0597 (does not live long enough), and the standard fixes.35 min
- Slices and stringsA slice is a reference to a part of a collection, like &s[0..5] or &arr[1..3]. String is owned, growable text on the heap; &str is a borrowed view of text, and string literals are &str. Slice ranges count BYTES, and text is stored as UTF-8, so a Hindi letter takes 3 bytes: slicing in the middle of a character panics.30 min
- LifetimesA lifetime is the stretch of code during which a reference is valid. Usually the compiler works lifetimes out by itself. When a function returns a reference that could come from more than one input, you name the lifetime, as in fn longest<'a>(x: &'a str, y: &'a str) -> &'a str. The annotation does not make anything live longer; it only describes how the references relate.35 min
Intermediate
Weeks 6–10. Structs, enums and pattern matching, error handling, collections, modules, traits, generics, closures, iterators and smart pointers. After this level you can design and build a well-organised Rust library or app.
1Structs, enums and pattern matching0/4 topics▼
Group data with structs, add behaviour with methods, model choices with enums, replace null with Option, and take values apart with match, if let and let else. After this module you can design your own types and handle every case of a value safely.
- Structs: your own data typesA struct groups related values under one name, each with a named field and a type. You create one with StructName { field: value, ... } and read fields with a dot. Rust also has tuple structs (fields without names) and unit structs (no fields). Add #[derive(Debug)] to print a struct with {:?}.25 min
- Methods and associated functionsMethods are functions attached to a type, written inside an impl block. Their first parameter is self: &self to read, &mut self to change, or self to take ownership. Functions in impl without self are associated functions, called with Type::name(), and a function named new is the usual way to build an instance.25 min
- Enums and OptionAn enum is a type whose value is exactly one of a fixed set of variants, and each variant can carry its own data. Rust has no null; instead, a value that may be missing has the type Option<T>, which is either Some(value) or None. The compiler forces you to handle None before you can use the value.30 min
- Pattern matching: match, if let and let elsematch compares a value against patterns and runs the arm that fits; it must cover every possible case, so you can never forget one. Patterns can bind values, use ranges, combine alternatives with | and add guards with if. For one interesting case, if let and let else are shorter, and while let loops while a pattern matches.30 min
2Error handling and collections0/5 topics▼
When to panic and when to return a Result, the ? operator, your own error types, and the everyday collections Vec, HashMap and HashSet. After this module you can write programs that fail gracefully with clear messages and that store, look up and count real data.
- panic! and unrecoverable errorsA panic stops the current thread with an error message; it is for bugs and situations that should never happen. unwrap() and expect() panic when a value is None or Err. They are fine in quick experiments, tests and truly impossible cases, but real programs should usually return errors instead of crashing.20 min
- Result and the ? operatorResult<T, E> is an enum with two variants: Ok(T) for success and Err(E) for failure. Functions that can fail return a Result, and the caller must deal with both cases. The ? operator is a shortcut: on Ok it gives the value, on Err it returns the error from the current function at once.30 min
- Custom error typesReal programs have several kinds of failure. An error enum lists them, one variant per kind, so callers can react to each. Implement Display (for the message) and std::error::Error, and add From conversions so ? converts lower-level errors automatically. The thiserror crate writes this code for libraries; anyhow is a convenient catch-all for applications.30 min
- Vec<T>: growable listsVec<T> is a growable list of values of one type, stored on the heap. Create one with Vec::new() or vec![...], add with push, remove with pop, and read with v[i] (panics if out of range) or v.get(i) (returns an Option). Loop with for x in &v to read and for x in &mut v to change, and remember you cannot push while holding a reference into the Vec.25 min
- HashMap and HashSetHashMap<K, V> stores key-value pairs and finds a value by its key very fast. insert adds or replaces, get returns an Option, and the entry API (map.entry(k).or_insert(0)) is the neat way to update counts. HashSet<T> stores unique values only. Neither keeps any order; use BTreeMap or BTreeSet when you need sorted keys.30 min
3Modules, crates, traits and generics0/4 topics▼
Organise code into modules and crates, use libraries from crates.io, describe shared behaviour with traits, write code that works for many types with generics, and choose between generics and trait objects. After this module you can structure a real project and write reusable, type-safe code.
- Packages, crates and modulesA crate is one compiled unit: a binary (a program with main) or a library. A package is a folder with Cargo.toml that holds one or more crates. Inside a crate, mod splits code into modules, pub makes items visible outside their module, and use brings names into scope. cargo add downloads libraries from crates.io.30 min
- Traits: shared behaviourA trait lists methods that a type promises to provide, like an interface in Java or C#. You implement a trait for a type with impl Trait for Type, and traits can have default methods. Many standard traits (Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Default) can be derived, and Display lets {} print your type.30 min
- Generics and trait boundsGenerics let you write one function or struct that works with many types, using a type parameter like T. Trait bounds (T: PartialOrd + Copy) say what T must be able to do. impl Trait is a short way to write a bound. The compiler makes a separate copy for each concrete type used (monomorphization), so generics cost nothing at run time.30 min
- Trait objects and dynamic dispatchA trait object (dyn Trait) lets you use values of different types through one trait, for example a Vec<Box<dyn Shape>> holding circles and squares together. The method to call is found at run time through a table of function pointers (a vtable). Use generics when the type is known at compile time and you want speed; use trait objects when you need a mixed collection or want to choose the type at run time.25 min
4Closures, iterators and smart pointers0/4 topics▼
Closures that capture their surroundings, iterator chains that are as fast as loops, and the smart pointers Box, Rc, RefCell and Weak for heap data, shared ownership and interior mutability. After this module you can write clean data-processing pipelines and choose the right pointer for shared or recursive data.
- ClosuresA closure is a small function without a name, written |x| x + 1, that can use variables from the place where it is created. It captures them by reference, by mutable reference or by value (with move). Depending on how it uses what it captured, a closure implements Fn, FnMut or FnOnce, which decides where it can be passed.30 min
- IteratorsAn iterator produces items one at a time through its next() method. iter() borrows items, iter_mut() borrows them mutably, and into_iter() takes ownership. Adapters like map, filter, enumerate and zip build a lazy chain that does nothing until a consumer such as sum, count, collect, fold or find runs it. Iterator chains compile to code as fast as hand-written loops.30 min
- Box<T>: values on the heapBox<T> is the simplest smart pointer: it puts a value on the heap and owns it, and the heap memory is freed when the Box is dropped. Use it for recursive types (a type that contains itself), for trait objects (Box<dyn Trait>), and occasionally to move a large value around cheaply.25 min
- Rc, RefCell and WeakRc<T> (reference counted) lets several owners share one value; it is freed when the last owner is dropped. RefCell<T> allows changing a value through a shared reference by checking the borrowing rules at run time instead of compile time, panicking if they are broken. Rc<RefCell<T>> gives shared, changeable data. Reference cycles leak memory; Weak<T> breaks them. Both Rc and RefCell are for a single thread.35 min
Expert
Weeks 11–16. Concurrency and async, testing, tooling and unsafe, real projects (CLI, axum web API, WebAssembly) and interview preparation. After this level you can ship real Rust software and apply for Rust jobs.
1Concurrency and async0/4 topics▼
Run work in parallel with threads, pass messages through channels, share state safely with Arc and Mutex, understand Send and Sync, and handle thousands of waiting tasks with async Rust and the tokio runtime. After this module you can write concurrent programs that the compiler has checked for data races, and choose between threads and async.
- ThreadsA thread is a separate line of execution that runs at the same time as others, so a program can use several CPU cores. std::thread::spawn starts one and returns a JoinHandle; join() waits for it to finish. Spawned threads usually need move closures, because they may outlive the variables they use; std::thread::scope lets threads borrow local data safely.30 min
- Message passing with channelsA channel sends values from one thread to another. std::sync::mpsc::channel() returns a Sender (tx) and a Receiver (rx); mpsc means multiple producers, single consumer. send moves the value into the channel, so the sender cannot touch it afterwards. Clone tx for several producers, and loop over rx to receive until every sender is dropped.25 min
- Shared state: Arc, Mutex, Send and SyncTo share changeable data between threads, wrap it in a Mutex (only one thread can lock it at a time) and share the Mutex with Arc (an atomically reference-counted pointer). lock() returns a guard that unlocks automatically when dropped. The marker traits Send and Sync tell the compiler which types may move to or be shared between threads; Rc is neither, so it cannot cross threads.35 min
- Async Rust with tokioAsync Rust handles many tasks that spend most of their time waiting, such as network requests, with few threads. An async fn returns a Future that does nothing until it is awaited, and a runtime such as tokio runs the futures. Use #[tokio::main], .await, tokio::spawn and tokio::join!, and never block the runtime with slow synchronous work.35 min
2Testing, tooling and unsafe Rust0/4 topics▼
Write unit tests, integration tests and doc tests with cargo test; keep code clean with rustfmt, Clippy and cargo doc; understand editions; and learn what unsafe Rust really allows, what it does not switch off, and how to keep it small and safe. After this module you can test and maintain a Rust project like a professional and read unsafe code with confidence.
- Unit testsA unit test checks one small piece of code. In Rust you write tests in a #[cfg(test)] mod tests block in the same file, mark each test function with #[test], and check results with assert!, assert_eq! and assert_ne!. cargo test compiles and runs them all; a panic means the test failed.30 min
- Integration tests and doc testsIntegration tests live in the tests/ folder; each file is a separate crate that can only use your library's public API, just like a real user. Doc tests are code examples inside /// documentation comments, and cargo test runs them too, so your examples never go out of date.25 min
- Tooling: rustfmt, Clippy, docs and editionscargo fmt formats code in the standard style; cargo clippy points out bugs and non-idiomatic code; cargo doc builds documentation; cargo check is the fastest way to find errors. Editions (2015, 2018, 2021, 2024) let Rust improve without breaking old code, and cargo fix --edition helps you upgrade. Run fmt, clippy and test on every push.25 min
- Unsafe Rust: what it is and is notunsafe marks code where you, not the compiler, promise that memory rules hold. It unlocks five extra abilities, such as dereferencing raw pointers and calling C functions, but it does NOT turn off the borrow checker or type checks. Good Rust keeps unsafe tiny, explains each block with a // SAFETY: comment, wraps it in a safe API, and tests it with tools like Miri.30 min
3Real projects: CLI, web and WebAssembly0/4 topics▼
Build a command-line tool with clap, read and write JSON with serde, create a small web API with axum on tokio, and compile Rust to WebAssembly for the browser. After this module you can ship three kinds of real Rust software and know which tools each one needs.
- Building a CLI toolCommand-line tools are one of Rust's strongest areas: one fast binary with no runtime to install. Read arguments with std::env::args or, better, the clap crate with #[derive(Parser)]. Keep main.rs thin and put the logic in lib.rs, return Result from functions, print errors to stderr with eprintln!, and exit with a non-zero code on failure.35 min
- Serde and JSONserde is Rust's standard way to convert data to and from formats like JSON. Add #[derive(Serialize, Deserialize)] to a struct, then use serde_json::to_string to write JSON and serde_json::from_str to read it into a typed struct. Attributes such as #[serde(rename_all = "camelCase")] match other naming styles, and Option fields handle missing values.25 min
- Rust for the web with axumaxum is a popular web framework from the tokio project. You build a Router that maps paths and HTTP methods to async handler functions. Handlers receive data through extractors such as Path, Query, Json and State, and return types like Json, a status code, or a tuple of both. axum 0.8 writes path parameters as /{id}.35 min
- Rust and WebAssemblyWebAssembly (Wasm) is a compact binary format that browsers run at near-native speed next to JavaScript. Rust compiles to it with the wasm32-unknown-unknown target. wasm-bindgen generates the glue so JavaScript can call your #[wasm_bindgen] functions, and wasm-pack is a common helper that builds a ready-to-import package. Use it for heavy computation in the browser, not for ordinary page logic.30 min
4Rust careers and interviews0/4 topics▼
Where Rust is used and what the job market honestly looks like (including India), the interview questions you will be asked on ownership, borrowing, lifetimes, traits, errors, smart pointers and concurrency, with model answers, and how to build a portfolio and keep learning. After this module you can plan your Rust career and answer common interview questions clearly.
- Where Rust is used and the job marketRust is used for systems and infrastructure, cloud and networking, developer tools, embedded devices, blockchains and WebAssembly. Rust-first jobs are fewer than Java, Python or JavaScript jobs, especially for freshers in India, and they often ask for systems or backend experience. The best strategy: combine Rust with a strong general skill (backend, systems or blockchain) and show real projects.25 min
- Interview questions: ownership, borrowing and lifetimesAlmost every Rust interview starts with ownership. Be ready to explain the three ownership rules, move versus copy versus clone, the borrowing rules and why they prevent data races, String versus &str, what lifetimes mean and when you must write them, and why a function cannot return a reference to a local variable. Answer in short sentences with a tiny example.35 min
- Interview questions: traits, errors, pointers and concurrencyAfter ownership, interviews move to traits and generics (static versus dynamic dispatch), error handling (Option, Result, ?, panic), smart pointers (Box, Rc, RefCell, Arc), concurrency (Send, Sync, Mutex, channels) and async (futures, runtimes, blocking). Expect short "what does this print" or "why does this not compile" snippets too.35 min
- Portfolio, open source and a learning planBuild three or four real projects that show different skills: a CLI tool, an axum API with a database, a WebAssembly demo, and a small library published on crates.io. Contribute to open source through "good first issue" labels. Keep practising with Rustlings, Rust by Example and Exercism, and follow a 90-day plan after this course.25 min
🎓 Final exam and certificate
37 questions, 60 minutes, pass mark 70%. Pass it to get a certificate with your name.