Bird
Raised Fist0
Rustprogramming~15 mins

Matching multiple patterns in Rust - Deep Dive

Choose your learning style10 modes available
Overview - Matching multiple patterns
What is it?
Matching multiple patterns in Rust means checking if a value fits any one of several possible shapes or values in a single match arm. Instead of writing separate arms for each pattern, you can combine them using the | symbol. This helps write cleaner and shorter code when you want to do the same thing for different cases. It is a way to compare a value against many options at once.
Why it matters
Without matching multiple patterns, programmers would write repetitive code for each case that behaves the same way. This makes code longer, harder to read, and more error-prone. Matching multiple patterns saves time and reduces mistakes by grouping similar cases together. It also makes programs easier to maintain and understand, especially when handling many possible inputs.
Where it fits
Before learning this, you should know basic Rust syntax and how the match statement works with single patterns. After this, you can learn about more advanced pattern matching features like destructuring, guards, and binding. Matching multiple patterns is a stepping stone to writing concise and expressive Rust code.
Mental Model
Core Idea
Matching multiple patterns lets you check if a value fits any one of several options in a single step, making code simpler and clearer.
Think of it like...
It's like choosing what to wear when the weather is either rainy or snowy — instead of checking each weather type separately, you say 'if it's rainy or snowy, wear boots' in one sentence.
┌─────────────────────────────┐
│          match value         │
├─────────────┬───────────────┤
│ Pattern A   │ Action A      │
├─────────────┼───────────────┤
│ Pattern B   │ Action B      │
├─────────────┼───────────────┤
│ Pattern C | Pattern D | ... │ Action C      │
└─────────────┴───────────────┘
Build-Up - 7 Steps
1
FoundationBasic match statement usage
🤔
Concept: Introduce how to use match with single patterns to decide actions based on a value.
In Rust, the match statement compares a value against patterns one by one. For example: let number = 2; match number { 1 => println!("One"), 2 => println!("Two"), 3 => println!("Three"), _ => println!("Other"), } This prints "Two" because number matches 2.
Result
Output: Two
Understanding the basic match structure is essential before combining patterns, as it shows how Rust checks values step-by-step.
2
FoundationPatterns and arms in match
🤔
Concept: Explain what patterns are and how each match arm has a pattern and an action.
A pattern is a shape or value Rust tries to match. Each arm in match has a pattern and code to run if matched. For example: match 'a' { 'a' => println!("Got a"), 'b' => println!("Got b"), _ => println!("Other"), } Here, 'a' and 'b' are patterns matching characters.
Result
Output: Got a
Knowing that patterns are like filters helps you see how matching multiple patterns combines these filters.
3
IntermediateCombining patterns with | operator
🤔Before reading on: do you think you can match multiple values in one arm by listing them separated by commas? Commit to your answer.
Concept: Introduce the | symbol to combine multiple patterns in one match arm.
Rust lets you write multiple patterns separated by | to match any of them in one arm. For example: let letter = 'c'; match letter { 'a' | 'e' | 'i' | 'o' | 'u' => println!("Vowel"), _ => println!("Consonant"), } This prints "Consonant" because 'c' is not a vowel.
Result
Output: Consonant
Using | reduces repetition and groups related cases, making code easier to read and maintain.
4
IntermediateMatching ranges and multiple patterns
🤔Before reading on: do you think you can combine ranges and single values with | in one match arm? Commit to your answer.
Concept: Show that you can mix ranges and single values with | to match multiple patterns.
You can combine ranges and single values using |. For example: let num = 7; match num { 1 | 3 | 5 | 7 | 9 => println!("Odd single-digit"), 10..=20 => println!("Between 10 and 20"), _ => println!("Other"), } This prints "Odd single-digit" because 7 matches one of the listed values.
Result
Output: Odd single-digit
Combining ranges and values with | gives flexible pattern matching for many cases in one arm.
5
IntermediateUsing multiple patterns with destructuring
🤔Before reading on: do you think you can use | with patterns that extract parts of data, like tuples? Commit to your answer.
Concept: Explain how to match multiple complex patterns that destructure data using |.
You can combine patterns that extract parts of data. For example: let point = (0, 5); match point { (0, y) | (y, 0) => println!("On an axis at {}", y), _ => println!("Elsewhere"), } This prints "On an axis at 5" because (0,5) matches (0, y).
Result
Output: On an axis at 5
Matching multiple destructured patterns lets you handle similar shapes with one action, saving code and clarifying intent.
6
AdvancedLimitations with guards and multiple patterns
🤔Before reading on: do you think you can use a single guard condition for all patterns combined with |? Commit to your answer.
Concept: Discuss how guards (extra if conditions) interact with multiple patterns and their limitations.
When using | to combine patterns, a guard applies to all patterns together. For example: let num = 4; match num { 1 | 2 | 3 if num % 2 == 0 => println!("Even small number"), _ => println!("Other"), } This will NOT match 2 because the guard applies only to 3. To apply guards properly, you must repeat patterns or use nested matches.
Result
Output: Other
Knowing guard limitations prevents bugs where some patterns unexpectedly skip the guard, ensuring correct matching logic.
7
ExpertCompiler optimizations and pattern matching order
🤔Before reading on: do you think the order of patterns with | affects performance or matching behavior? Commit to your answer.
Concept: Explain how Rust compiles multiple patterns and how order and complexity affect performance and exhaustiveness checks.
Rust compiles match arms into efficient code, often using jump tables or decision trees. When you combine patterns with |, the compiler checks them all together. The order of patterns in | does not affect matching behavior but can affect compile-time exhaustiveness checks. Complex patterns may cause the compiler to generate more code, impacting compile time and binary size. Understanding this helps write efficient and maintainable matches.
Result
No visible output, but better compiled code and warnings if patterns are incomplete.
Knowing compiler behavior helps write matches that are both correct and efficient, avoiding surprises in large codebases.
Under the Hood
Rust's match statement compiles into a decision tree or jump table that checks the input value against each pattern efficiently. When multiple patterns are combined with |, the compiler treats them as alternatives in the same branch, generating code that tests each pattern in order until one matches. This reduces duplicated code and improves runtime speed. Guards add conditional checks after pattern matching, but when combined with |, the guard applies to all patterns collectively, which can cause subtle behavior differences.
Why designed this way?
Rust's pattern matching was designed for safety, expressiveness, and performance. Combining multiple patterns with | avoids repetitive code and makes matches concise. The design balances ease of use with compiler optimizations. Alternatives like separate arms for each pattern would be verbose and error-prone. The guard limitation exists because applying different guards to individual patterns in one arm would complicate the syntax and compiler logic.
┌───────────────┐
│   match val   │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Check pattern1│
├───────────────┤
│ Check pattern2│
├───────────────┤
│ ...           │
├───────────────┤
│ If any match  │
│   run action  │
└───────────────┘
       │
       ▼
  (optional guard)
       │
       ▼
  Execute code or continue
Myth Busters - 4 Common Misconceptions
Quick: Does a guard apply separately to each pattern in a combined arm with |, or to all patterns together? Commit to your answer.
Common Belief:A guard applies individually to each pattern separated by | in a match arm.
Tap to reveal reality
Reality:A guard applies to the entire combined pattern as a whole, not to each pattern separately.
Why it matters:Misunderstanding this causes unexpected matches or misses, leading to bugs where some patterns bypass the guard.
Quick: If you list multiple patterns with |, does the order affect which pattern matches first? Commit to your answer.
Common Belief:The order of patterns separated by | affects which pattern matches first and thus the behavior.
Tap to reveal reality
Reality:All patterns combined with | are treated as alternatives in the same arm; order does not affect which matches first because they share the same action.
Why it matters:Thinking order matters here can lead to unnecessary code rearrangement and confusion about match behavior.
Quick: Can you use commas instead of | to separate multiple patterns in a match arm? Commit to your answer.
Common Belief:You can separate multiple patterns with commas in a single match arm.
Tap to reveal reality
Reality:Rust requires the | symbol to combine multiple patterns; commas separate different match arms.
Why it matters:Using commas instead of | causes syntax errors and confusion about match syntax.
Quick: Does combining multiple patterns with | always make the code faster? Commit to your answer.
Common Belief:Combining multiple patterns with | always improves runtime performance.
Tap to reveal reality
Reality:Combining patterns improves code clarity but does not always improve runtime speed; the compiler optimizes matches regardless of | usage.
Why it matters:Assuming | always improves speed can mislead optimization efforts and distract from writing clear code.
Expert Zone
1
When combining patterns with |, the compiler checks exhaustiveness across all combined patterns, which can cause unexpected warnings if some patterns overlap or are unreachable.
2
Using | with complex destructuring patterns can increase compile time and binary size due to duplicated code paths internally, even if the source looks concise.
3
Guards combined with | apply to all patterns together, so to have different guards per pattern, you must split them into separate arms or use nested matches.
When NOT to use
Avoid combining patterns with | when each pattern requires a different guard or action, as this can cause logic errors. Instead, write separate match arms or use if-let chains. Also, for very complex patterns, splitting arms improves readability and compiler diagnostics.
Production Patterns
In real-world Rust code, matching multiple patterns is common for handling enums with many variants that share behavior, like error handling or input parsing. It is also used in state machines to group states with similar transitions. Experts carefully balance combining patterns for clarity with splitting arms for precise control.
Connections
Logical OR in Boolean algebra
Matching multiple patterns with | is like the OR operation combining multiple conditions.
Understanding how | combines patterns helps grasp how logical OR works in programming and math, showing a shared principle of combining alternatives.
Switch-case statements in other languages
Rust's match with multiple patterns replaces multiple case labels in switch statements.
Knowing this connection helps learners coming from other languages see how Rust improves on switch by allowing pattern matching and combining cases cleanly.
Decision trees in machine learning
Pattern matching compiles into decision trees that efficiently route inputs to outcomes.
Recognizing this link shows how Rust's match is an example of a decision tree, a concept used widely in AI and data science for classification.
Common Pitfalls
#1Using commas instead of | to combine patterns.
Wrong approach:match x { 1, 2, 3 => println!("One, two, or three"), _ => println!("Other"), }
Correct approach:match x { 1 | 2 | 3 => println!("One, two, or three"), _ => println!("Other"), }
Root cause:Confusing syntax for separating match arms (commas) with combining patterns (|).
#2Expecting guards to apply to each pattern separately in a combined arm.
Wrong approach:match x { 1 | 2 if x % 2 == 0 => println!("Even 1 or 2"), _ => println!("Other"), }
Correct approach:match x { 1 if x % 2 == 0 => println!("Even 1"), 2 if x % 2 == 0 => println!("Even 2"), _ => println!("Other"), }
Root cause:Misunderstanding that guard applies to all patterns combined, not individually.
#3Combining patterns with | but needing different actions.
Wrong approach:match x { 1 | 2 => println!("One"), // but want different messages for 1 and 2 _ => println!("Other"), }
Correct approach:match x { 1 => println!("One"), 2 => println!("Two"), _ => println!("Other"), }
Root cause:Trying to combine patterns that require distinct handling into one arm.
Key Takeaways
Matching multiple patterns with | lets you group several cases into one match arm, making code shorter and clearer.
Guards apply to all combined patterns together, so use separate arms if you need different conditions per pattern.
The order of patterns combined with | does not affect which matches first since they share the same action.
Using | is a powerful tool but requires understanding its syntax and limitations to avoid subtle bugs.
Rust compiles match statements efficiently, and combining patterns helps write expressive and maintainable code.

Practice

(1/5)
1. In Rust, which symbol is used to match multiple patterns in a single match arm?
easy
A. |
B. &
C. +
D. &&

Solution

  1. Step 1: Recall the syntax for matching multiple patterns

    Rust uses the vertical bar | to separate multiple patterns in one match arm.
  2. Step 2: Identify the correct symbol

    The symbol | means "or" in pattern matching, allowing multiple cases to be handled together.
  3. Final Answer:

    | -> Option A
  4. Quick Check:

    Multiple patterns use | in match arms [OK]
Hint: Use | to combine patterns in one match arm [OK]
Common Mistakes:
  • Using & instead of |
  • Confusing + with pattern separator
  • Using && which is logical AND, not pattern OR
2. Which of the following Rust match arms correctly matches the values 1, 2, or 3 using multiple patterns?
easy
A. 1 & 2 & 3 => println!("Matched 1, 2, or 3"),
B. 1 | 2 | 3 => println!("Matched 1, 2, or 3"),
C. 1 + 2 + 3 => println!("Matched 1, 2, or 3"),
D. 1, 2, 3 => println!("Matched 1, 2, or 3"),

Solution

  1. Step 1: Check the syntax for multiple patterns

    Rust uses | to separate multiple patterns in a match arm, so 1 | 2 | 3 is correct.
  2. Step 2: Identify incorrect options

    & is not used for matching multiple patterns, + is arithmetic, and commas are invalid here.
  3. Final Answer:

    1 | 2 | 3 => println!("Matched 1, 2, or 3"), -> Option B
  4. Quick Check:

    Multiple patterns use | separator [OK]
Hint: Separate patterns with | inside match arms [OK]
Common Mistakes:
  • Using & instead of | for multiple patterns
  • Trying to separate patterns with commas
  • Using + which is arithmetic, not pattern matching
3. What will be the output of this Rust code?
let x = 2;
match x {
    1 | 2 | 3 => println!("Small number"),
    4 | 5 | 6 => println!("Medium number"),
    _ => println!("Other number"),
}
medium
A. Compilation error
B. Medium number
C. Small number
D. Other number

Solution

  1. Step 1: Identify which pattern matches x=2

    The first arm matches 1, 2, or 3. Since x is 2, it matches this arm.
  2. Step 2: Determine the output

    The matched arm prints "Small number" to the console.
  3. Final Answer:

    Small number -> Option C
  4. Quick Check:

    2 matches 1|2|3 arm [OK]
Hint: Check which pattern includes the value [OK]
Common Mistakes:
  • Choosing Medium number for 2
  • Thinking _ arm matches first
  • Assuming syntax error due to multiple patterns
4. Find the error in this Rust code snippet that tries to match multiple patterns:
let ch = 'a';
match ch {
    'a' | 'e' | 'i' | 'o' | 'u' => println!("Vowel"),
    'a' | 'b' => println!("Letter a or b"),
    _ => println!("Other"),
}
medium
A. Missing semicolon after println! macros
B. Match expression missing a default arm
C. Incorrect use of | operator for multiple patterns
D. Duplicate pattern 'a' in multiple arms causes unreachable code

Solution

  1. Step 1: Identify duplicate patterns in match arms

    The character 'a' appears in both the first and second arms, causing the second arm's 'a' pattern to be unreachable.
  2. Step 2: Understand Rust's pattern matching rules

    Rust does not allow unreachable patterns; the compiler will warn or error about the duplicate 'a'.
  3. Final Answer:

    Duplicate pattern 'a' in multiple arms causes unreachable code -> Option D
  4. Quick Check:

    Duplicate patterns cause unreachable code errors [OK]
Hint: Avoid repeating same pattern in multiple match arms [OK]
Common Mistakes:
  • Ignoring unreachable pattern warnings
  • Thinking | is invalid for multiple patterns
  • Missing default arm (actually present here)
5. You want to write a Rust function that returns "Weekend" for Saturday or Sunday, "Weekday" for Monday to Friday, and "Invalid" otherwise. Which match arm correctly uses multiple patterns to do this?
fn day_type(day: &str) -> &str {
    match day {
        ? => "Weekend",
        ? => "Weekday",
        _ => "Invalid",
    }
}
hard
A. "Saturday" | "Sunday", "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday"
B. "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday"
C. "Saturday" & "Sunday", "Monday" & "Tuesday" & "Wednesday" & "Thursday" & "Friday"
D. "Saturday" + "Sunday", "Monday" + "Tuesday" + "Wednesday" + "Thursday" + "Friday"

Solution

  1. Step 1: Use | to match multiple string patterns in one arm

    Rust allows multiple patterns separated by | to group cases like "Saturday" | "Sunday".
  2. Step 2: Check other options for invalid syntax

    Commas separate arms, not patterns; & and + are invalid for pattern matching.
  3. Final Answer:

    "Saturday" | "Sunday", "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday" -> Option A
  4. Quick Check:

    Use | to combine multiple string patterns [OK]
Hint: Use | to combine multiple string patterns in match arms [OK]
Common Mistakes:
  • Using commas instead of | inside match arms
  • Using & or + which are invalid for patterns
  • Forgetting to cover all weekdays or weekend days
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard