Syntax Cache
BlogMethodFeaturesHow It WorksBuild a Game
  1. Home
  2. Rust
Rust18 topics778+ exercises

Rust Syntax Practice

Write Rust from memory, not from compiler error messages.

Short daily reps. Spaced repetition automatically brings back what you keep forgetting.

You understand Rust conceptually. You get why the borrow checker exists. But when you're typing code, you still pause: Is it `&mut` or `mut &`? Does the lifetime go before or after the type? What's the turbofish syntax again?

The borrow checker isn't the hard part anymore. It's the syntax around it. Move semantics, lifetime annotations, trait bounds, match arms. These patterns need to be automatic, not something you reconstruct from first principles every time.

This isn't a Rust tutorial. It's targeted practice for developers who already know the concepts but want the syntax to stick. Ten minutes a day, and you stop fighting the compiler over things you already understand.

Popular topics include Rust Foundations Practice: Variables, Types & Basic Syntax, Rust Ownership & Borrowing Practice: Move Semantics & Borrow Rules, Rust References & Lifetimes Practice: Lifetime Annotations & Elision.

Built for Rust Learners

Great for
  • Systems programmers learning Rust who want syntax to become automatic.
  • Developers transitioning from garbage-collected languages.
  • Engineers preparing for Rust interviews or team onboarding.
  • Anyone who understands ownership but still trips over the syntax.
You'll be able to
  • Write ownership-correct code without fighting the borrow checker.
  • Get lifetime annotations right on the first try.
  • Use pattern matching idiomatically in match, if let, and while let.
  • Implement traits and use generics with confidence.
  • Handle errors elegantly with Result and the ? operator.

Practice by Topic

Pick a concept and train recall with small, focused reps.

57 exercisesGotchas included

Rust Foundations Practice

Stop mixing up let vs let mut, and know when to annotate types vs rely on inference.

Show 3 gotchasHide gotchas
  • Variables are immutable by default. let x = 5; cannot be reassigned.
  • Shadowing (let x = x + 1;) creates a new variable, not mutation.
  • Constants require type annotations: const MAX: u32 = 100;
Learn more
39 exercisesGotchas included

Rust Ownership & Borrowing Practice

Internalize ownership rules so the borrow checker stops surprising you.

Show 3 gotchasHide gotchas
  • Each value has exactly one owner. Assignment moves ownership.
  • You can have many &T OR one &mut T, never both.
  • References must always be valid. No dangling pointers.
Learn more
38 exercisesGotchas included

Rust References & Lifetimes Practice

Get lifetime annotations right without guessing.

Show 3 gotchasHide gotchas
  • Lifetime syntax goes after &: &'a str, not 'a &str.
  • Elision rules handle most cases. Add annotations when the compiler asks.
  • 'static means the reference is valid for the entire program.
Learn more
37 exercisesGotchas included

Rust Structs & Enums Practice

Define types confidently with structs, enums, Option, and Result.

Show 3 gotchasHide gotchas
  • Struct fields are private by default. Use pub for external access.
  • Option<T> is Some(value) or None, never null.
  • Result<T, E> is Ok(value) or Err(error). Handle both.
Learn more
52 exercisesGotchas included

Rust Pattern Matching Practice

Match, if let, and destructuring without forgetting arms or patterns.

Show 3 gotchasHide gotchas
  • Match must be exhaustive. Use _ as a catch-all.
  • if let is sugar for matching one pattern and ignoring the rest.
  • Destructure in patterns: Some(x), (a, b), Point { x, y }.
Learn more
51 exercisesGotchas included

Rust Traits & Generics Practice

Write generic code with trait bounds that the compiler accepts.

Show 3 gotchasHide gotchas
  • Trait bounds go after : in generics: fn foo<T: Clone>(x: T).
  • Use impl Trait for simple return types: -> impl Iterator.
  • The turbofish ::<> disambiguates generic types: parse::<i32>().
Learn more
59 exercisesGotchas included

Rust Collections & Iterators Practice

Chain iterator adapters without losing track of ownership.

Show 3 gotchasHide gotchas
  • .iter() borrows, .into_iter() takes ownership, .iter_mut() borrows mutably.
  • Iterators are lazy. Nothing happens until you .collect() or consume.
  • .collect() needs a type hint: .collect::<Vec<_>>().
Learn more
40 exercisesGotchas included

Rust Error Handling Practice

Propagate errors with ? and handle them idiomatically.

Show 3 gotchasHide gotchas
  • ? only works in functions returning Result or Option.
  • .unwrap() panics on error. Use .expect("msg") for better errors.
  • Chain ? for clean error propagation: file.read_to_string(&mut s)?.
Learn more
44 exercisesGotchas included

Rust Modules & Crates Practice

Organize code with mod, use, and pub without path confusion.

Show 3 gotchasHide gotchas
  • mod foo; looks for foo.rs or foo/mod.rs.
  • use crate::module::Item for absolute paths within your crate.
  • pub(crate) makes items visible within the crate only.
Learn more
59 exercisesGotchas included

Rust Strings Practice

Navigate String vs &str and string methods confidently.

Show 3 gotchasHide gotchas
  • String is owned and heap-allocated. &str is a borrowed slice.
  • You cannot index strings by integer. Use .chars() or slicing.
  • Strings are UTF-8. One character can be multiple bytes.
Learn more
53 exercisesGotchas included

Rust Closures Practice

Write closures with the right capture mode and trait bounds.

Show 3 gotchasHide gotchas
  • Closures capture by reference by default. Use move for ownership.
  • Closure traits: Fn (borrow), FnMut (mutable borrow), FnOnce (move).
  • Each closure has a unique anonymous type. Use impl Fn() or Box<dyn Fn()>.
Learn more
49 exercisesGotchas included

Rust Derive Traits Practice

Use derive macros and implement common traits correctly.

Show 3 gotchasHide gotchas
  • #[derive(Debug)] enables {:?} formatting.
  • Clone is explicit copy. Copy is implicit bitwise copy for simple types.
  • Deriving PartialEq compares all fields. Eq adds reflexivity guarantee.
Learn more
39 exercisesGotchas included

Rust Smart Pointers Practice

Choose Box, Rc, RefCell, or Arc for the right ownership model.

Show 3 gotchasHide gotchas
  • Box<T> for heap allocation with single owner.
  • Rc<T> for shared ownership (single-threaded). Arc<T> for threads.
  • RefCell<T> enables interior mutability with runtime borrow checking.
Learn more
52 exercisesGotchas included

Rust Concurrency Practice

Write thread-safe code with channels, mutexes, and Send/Sync.

Show 3 gotchasHide gotchas
  • Send means safe to transfer between threads. Sync means safe to share.
  • Mutex<T> requires .lock(). The guard auto-unlocks on drop.
  • Use channels (mpsc) for message passing between threads.
Learn more
25 exercisesGotchas included

Rust Macros Practice

Understand macro syntax and when to use declarative vs procedural.

Show 3 gotchasHide gotchas
  • Declarative macros use macro_rules! with pattern matching.
  • Macros are expanded at compile time, before type checking.
  • Use $() for repetition: $($x:expr),* matches comma-separated expressions.
Learn more
35 exercisesGotchas included

Rust Async Practice

Write async functions and use .await correctly.

Show 3 gotchasHide gotchas
  • async fn returns impl Future. Call .await to run it.
  • Futures are lazy. Nothing happens until you poll or await them.
  • .await can only be used inside async functions or blocks.
Learn more
25 exercisesGotchas included

Rust Testing Practice

Structure tests with #[test], assert macros, and test modules.

Show 3 gotchasHide gotchas
  • #[test] marks a function as a test. Run with cargo test.
  • assert!, assert_eq!, assert_ne! for test assertions.
  • #[cfg(test)] compiles the module only during testing.
Learn more
24 exercisesGotchas included

Rust Unsafe Practice

Use unsafe blocks correctly for raw pointers and FFI.

Show 3 gotchasHide gotchas
  • unsafe unlocks: raw pointer derefs, unsafe fn calls, mutable statics, FFI.
  • Raw pointers (*const T, *mut T) can be null and require manual safety.
  • Keep unsafe blocks minimal. Wrap them in safe abstractions.
Learn more

Rust Cheat Sheets

Copy-ready syntax references for quick lookup

Ownership & BorrowingPattern MatchingError HandlingTraits & GenericsIteratorsString TypesLifetimesEnumsRegex (regex crate)

What You'll Practice

Real Rust patterns you'll type from memory

Mutable borrow
fn modify(s: &mut String) {
    s.push_str(" world");
}
Lifetime annotation
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() { x } else { y }
}
Match with destructuring
match point {
    Point { x: 0, y } => println!("on y-axis at {y}"),
    Point { x, y: 0 } => println!("on x-axis at {x}"),
    Point { x, y } => println!("at ({x}, {y})"),
}
Trait bound
fn print_all<T: Display>(items: &[T]) {
    for item in items {
        println!("{item}");
    }
}
Iterator chain
let sum: i32 = numbers
    .iter()
    .filter(|&n| n % 2 == 0)
    .map(|n| n * n)
    .sum();
Error propagation
fn read_config() -> Result<Config, Error> {
    let contents = fs::read_to_string("config.toml")?;
    let config: Config = toml::from_str(&contents)?;
    Ok(config)
}
Option handling
if let Some(value) = optional {
    println!("Got: {value}");
}
Module declaration
mod utils;
use utils::helper_function;

pub fn main() {
    helper_function();
}

Sample Exercises

Example 1Difficulty: 2/5

Define a function `add` that takes two i32 parameters and returns their sum.

fn add(a: i32, b: i32) -> i32 {
    a + b
}
Example 2Difficulty: 2/5

Fill in the call to borrow `name` mutably.

&mut name
Example 3Difficulty: 2/5

Fill in the match arm to return "zero" when n is 0.

"zero"

Done Googling Rust syntax?

Ten minutes a day. No setup. The syntax sticks.

Why this works

Rust's syntax is notoriously tricky to remember: lifetimes, turbofish, trait bounds. Spaced repetition ensures these patterns stay fresh even when you're not writing Rust daily.

What to expect

Week 1: You'll see your weak spots clearly: maybe lifetime annotations, maybe the difference between `&` and `&mut`, maybe match arm syntax. The algorithm surfaces patterns you blank on.

Week 2-4: Intervals start stretching. Things you got right move to 2-day, 4-day, then weekly reviews. Ownership rules start feeling natural.

Month 2+: Most syntax you need daily is automatic. Reviews take 10-15 minutes. You still practice, but now it's maintenance. The borrow checker stops surprising you.

FAQ

Is this for complete Rust beginners?

Not for zero-experience beginners. You should understand basic programming concepts. The foundations exercises start with the simplest Rust syntax (variables, functions, types), so you can start there if you're new to Rust specifically. But this is practice, not a tutorial—pair it with The Rust Book or Rustlings for concept learning.

Will I learn the borrow checker?

Yes! Multiple concept areas cover ownership, borrowing, and lifetimes, the core of Rust's memory safety. You'll practice until the rules are second nature.

Are there execution-based exercises?

Currently exercises use token-based comparison for grading. Code execution support is planned for a future release.

What Rust version is covered?

Exercises cover stable Rust syntax. We avoid nightly-only features to ensure what you learn works everywhere.

How is this different from Rustlings?

Rustlings teaches Rust concepts through exercises. This platform uses spaced repetition to make the syntax permanent. They complement each other: learn with Rustlings, retain with SyntaxCache.

Sources
The Rust Programming Language (The Book)Rust By ExampleThe Rustonomicon (Advanced)Rust Standard Library Documentation

Try it. It takes two minutes.

Free daily exercises with spaced repetition. No credit card required.

Syntax Cache

Build syntax muscle memory with spaced repetition.

Product

  • Pricing
  • Our Method
  • Daily Practice
  • Design Patterns
  • Interview Prep

Resources

  • Blog
  • Compare
  • Cheat Sheets
  • Vibe Coding
  • Muscle Memory

Languages

  • Python
  • JavaScript
  • TypeScript
  • Rust
  • SQL
  • GDScript

Legal

  • Terms
  • Privacy
  • Contact

© 2026 Syntax Cache

Cancel anytime in 2 clicks. Keep access until the end of your billing period.

No refunds for partial billing periods.