Overview
A switch statement in Swift can match more than exact values. It can also match intervals, which means ranges of values like 1...10 or 0..<100.
This is useful whenever a number belongs to a category: scores, ages, temperatures, distances, counts, coordinates, and so on.
Basic Interval Matching
Here is a simple grade example using closed ranges:
let score = 87
switch score {
case 90...100:
print("A")
case 80...89:
print("B")
case 70...79:
print("C")
case 60...69:
print("D")
default:
print("F")
}The ... operator creates a closed range. That means 80...89 includes both 80 and 89.
Closed Ranges
A closed range includes the lower and upper bounds:
let age = 16
switch age {
case 0...12:
print("Child")
case 13...17:
print("Teen")
case 18...64:
print("Adult")
default:
print("Senior")
}Closed ranges are a good fit when both endpoints are meaningful and included in the category.
Half-Open Ranges
A half-open range includes the lower bound but excludes the upper bound. You write it with ..<:
let percentage = 72
switch percentage {
case 0..<50:
print("Needs improvement")
case 50..<75:
print("Passing")
case 75..<90:
print("Strong")
case 90...100:
print("Excellent")
default:
print("Outside expected range")
}In this example, 50..<75 includes 50, but does not include 75. A value of 75 moves into the next case.
Partial Ranges
Swift also supports one-sided ranges. These are helpful when a category has only one meaningful boundary:
let temperature = -4
switch temperature {
case ..<0:
print("Freezing")
case 0...20:
print("Cool")
case 21...30:
print("Warm")
case 31...:
print("Hot")
default:
print("Unknown")
}..<0 matches anything below zero. 31... matches anything from 31 upward.
Order Matters
Swift checks cases from top to bottom and runs the first match. If your intervals overlap, the earlier case wins.
let points = 95
switch points {
case 90...100:
print("Gold")
case 95...100:
print("Perfect finish")
default:
print("Keep going")
}The second case can never run because 95...100 is already covered by 90...100. Keep your ranges non-overlapping whenever possible, or put the most specific ranges first.
Matching Tuples with Ranges
Switch interval matching becomes even more expressive when you combine it with tuples. For example, you can classify a point on a simple coordinate plane:
let point = (x: 4, y: -2)
switch point {
case (0, 0):
print("Origin")
case (-10...10, -10...10):
print("Inside the target area")
default:
print("Outside the target area")
}The tuple case (-10...10, -10...10) matches when both the x value and y value fall inside their intervals.
Common Mistakes
Overlapping ranges accidentally
If two cases can match the same value, Swift uses the first one. That can make later cases unreachable or misleading.
Forgetting values outside the expected range
If the value can come from user input, a server, or another outside source, include a default case for unexpected values.
Mixing up closed and half-open ranges
Remember: 1...5 includes 5, but 1..<5 stops before 5.
Quick Reference
| Pattern | What It Does |
|---|---|
case 1...5: | Matches 1 through 5, including both endpoints |
case 1..<5: | Matches 1 up to, but not including, 5 |
case ..<0: | Matches anything less than 0 |
case 100...: | Matches 100 and anything above it |
case (-10...10, -10...10): | Matches a tuple where both values are inside the listed ranges |
default: | Catches values that do not match any interval above it |
Summary
- Interval matching lets switch cases match ranges of values.
- Use
...for closed ranges where both endpoints are included. - Use
..<for half-open ranges where the upper bound is excluded. - Use one-sided ranges like
..<0and100...when only one boundary matters. - Case order matters because Swift runs the first matching case.
- Ranges can also be used inside tuple patterns.
The big idea is that switch is not limited to exact equality checks. When your logic is based on categories of numbers, interval matching often makes the code easier to read than a long chain of if statements.