Code of the Day
IntermediateTypes & traits

Lab: Types & traits

Scenario questions on enum pattern matching, trait objects, and iterator chains to consolidate the types-and-traits module.

Lab · optionalRustIntermediate15 min
Recommended first
By the end of this lesson you will be able to:
  • Predict match arm outcomes without running code
  • Reason about trait objects and dynamic dispatch
  • Trace iterator adapter chains to their output

This lab consolidates the types-and-traits module through scenario questions. Work through them before checking explanations — predicting outcomes and then reading the reasoning is more effective than reading first.

Part 1: Enum pattern matching

Knowledge check

  1. 1.
    What does this code print?

    enum Coin { Penny, Dime, Quarter(String) }
    let c = Coin::Quarter(String::from("Alaska"));
    match c {
        Coin::Penny => println!("1"),
        Coin::Quarter(state) if state.starts_with("A") => println!("25 + {}", state),
        _ => println!("other"),
    }
  2. 2.
    You define an enum with 6 variants and write a match with 5 arms plus a wildcard _. You add a 7th variant. Does the code still compile?
  3. 3.
    if let Ok(v) = some_result { ... } is exactly equivalent to a match with one Ok arm and a wildcard Err arm.

Part 2: Trait objects and dynamic dispatch

Knowledge check

  1. 1.
    What is a trait object (&dyn Trait or Box<dyn Trait>)?
  2. 2.
    When should you prefer Box<dyn Trait> over a generic T: Trait?
  3. 3.
    A trait with a method that returns Self can be used as a trait object (dyn Trait).

Part 3: Iterator chains

Knowledge check

  1. 1.
    What does this expression produce?

    let result: Vec<i32> = (1..=5)
        .map(|x| x * 2)
        .filter(|x| x > &5)
        .collect();
  2. 2.
    You have let v: Vec<Vec<i32>> = vec![vec![1,2], vec![3,4]];. Which expression produces [1, 2, 3, 4] as a Vec<i32>?
  3. 3.
    Calling .map(|x| x * 2) on a vector immediately doubles all its elements.

Putting it together

The types-and-traits module builds a layered picture: enums model data shapes, traits describe capabilities, generics write code once for many types, and iterators apply those abstractions to sequences. Together these form the core of idiomatic Rust — most real Rust code uses all four constantly.

If any question surprised you, revisit the corresponding lesson. The best follow-up is to open a Rust playground or cargo new scratch and try the code yourself — the compiler's errors are precise teaching tools.

Where to go next

You've completed the intermediate track. The advanced track starts with concurrency — where ownership, Send/Sync, and closures combine to make data-race-free multi-threaded programming a compile-time guarantee.

Finished reading? Mark it complete to track your progress.

On this page