match: Choosing by Value
The club's weekly plan depends on the day: intervals on Tuesday, a long run at the weekend, easy running otherwise. Writing that as if day == "Tue" … else if day == "Sat" … works, but it repeats day == on every line. A match names the value once and lists the cases.
The rule
Name the value once, list the cases, end with
_.
val day = "Sat"
val session = day match
case "Tue" => "track intervals"
case "Sat" | "Sun" => "long run"
case _ => "easy run or rest"
// session is "long run"day matchstarts the match. Eachcasegives a pattern, an arrow=>, and the value to produce.- Cases are tried top to bottom, and the first that fits wins. There is no fall-through into the next case, so no
breakis needed. "Sat" | "Sun"lists two alternatives; either one fits that case.case _fits anything. It plays the role of the finalelse.- Like
if, amatchis an expression, and here every case gives aString.
A guard adds a condition to a case with if:
val label = km match
case 0.0 => "rest day"
case k if k >= 21.1 => "half marathon"
case k if k >= 10 => "long run"
case _ => "easy run"Here k is a new name for the value being matched, and the guard decides whether the case fits.
If no case fits, the program throws a MatchError at run time. That is why a match on open-ended values, such as strings or numbers, should end with case _.
This is only a first taste. The Pattern Matching topic later in the roadmap shows how match can also take data apart.
The shortcut
Write the specific cases first and the catch-all last, just as in an else if chain. Then ask: "Can any value reach the bottom without a case?" If yes, add case _.
Name the value
"Mon" matchstarts checking the cases.
Drills
Answer fast — trust the rule.
In the session match above, what is the session for "Sun"?
What does case _ do?
A match on day names has no case _, and the value is "Mon", which no case lists. What happens?
Using the label match above, what does a 15.0 km run get?
After a case in a Scala match runs, what happens next?
Remember
value matchtries cases top to bottom, and the first fitting case gives the value.- Specific cases first,
case _last; use guards such ascase k if k >= 10for ranges. - Trap: leaving out
case _on open-ended values means a MatchError at run time.
