Or Patterns, Ranges and Guards
Three extensions that cover most practical cases of value discrimination.
Or patterns: multiple alternatives
The | operator groups several patterns into a single arm. Instead of repeating the
same body for each value, you list them separated by |. Works with
literals of any type.
Days of the week, number parity and booleans with or-pattern.
// Feature: Or-patterns — multiple alternatives in one arm
// Syntax: `pat1 | pat2 | pat3 => body`
// When to use: group several inputs that trigger the same action,
// without repeating the body.
let day = "Saturday"
let kind = match day {
"Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday" => "weekday",
"Saturday" | "Sunday" => "weekend",
_ => "unknown",
}
print(kind) // weekend
// Numeric.
let n = 5
let parity_or_special = match n {
0 => "zero",
1 | 3 | 5 | 7 | 9 => "small odd",
2 | 4 | 6 | 8 => "small even",
_ => "large",
}
print(parity_or_special) // small odd
// Or-patterns with bool.
let flag = false
let label = match flag {
true | false => "any",
}
// exhaustive in a single line
print(label) // any
// expected:
// weekend
// small odd
// any
Numeric ranges
The start..=end pattern (inclusive on both ends) matches any number
within the interval. Avoids listing each literal when the values form a
contiguous block. Works with int and float.
Ranges to classify ages, grades and temperatures.
// Feature: Range patterns — numeric intervals
// Syntax: `start..=end` (inclusive)
// When to use: classify numeric values into ranges instead of
// listing each literal.
let age = 25
let group = match age {
0..=12 => "child",
13..=19 => "teenager",
20..=64 => "adult",
_ => "senior",
}
print(group) // adult
// Scores -> letter grades.
let score = 87
let grade = match score {
90..=100 => "A",
80..=89 => "B",
70..=79 => "C",
60..=69 => "D",
_ => "F",
}
print(grade) // B
// Float ranges.
let temp = 22.5
let weather = match temp {
-100.0..=0.0 => "freezing",
0.0..=15.0 => "cold",
15.0..=25.0 => "pleasant",
25.0..=40.0 => "hot",
_ => "extreme",
}
print(weather) // pleasant
// expected:
// adult
// B
// pleasant
Guards: extra condition on the arm
A guard (pat if cond) adds an arbitrary boolean condition to the
arm. The pattern is tested first; if it matches, the guard is evaluated — if it is
false, the match engine tries the next arm. Guards are ideal for
logic that ranges and literals cannot express (parity, comparison
between fields, external predicates).
Parity, grades with score in the label and a guard combined with or-pattern.
// Feature: Guards — extra `if expr` condition on the arm
// Syntax: `pat if cond => body`
// When to use: refine a pattern with logic that ranges/literals
// can't cover (parity, comparing fields, custom predicates).
let n = 12
let kind = match n {
x if x < 0 => "negative",
0 => "zero",
x if x % 2 == 0 => "positive even",
_ => "positive odd",
}
print(kind) // positive even
// Guards with binding.
let score = 75
let grade = match score {
s if s >= 90 => "A ({s})",
s if s >= 80 => "B ({s})",
s if s >= 70 => "C ({s})",
s => "F ({s})",
}
print(grade) // C (75)
// Guards combined with or-pattern — guard applies to the whole arm.
let day = "Sunday"
let busy = true
let plan = match day {
"Saturday" | "Sunday" if busy => "weekend work",
"Saturday" | "Sunday" => "rest",
_ => "weekday",
}
print(plan) // weekend work
// expected:
// positive even
// C (75)
// weekend work
Challenge
In the ranges example, add a 65..=100 => "senior" arm before the
_ and remove the _. Run it and see whether the compiler accepts the match as exhaustive.
See also