You already know how to branch with if / else if chains. Scala has a second branching tool that is usually the better one: match. It looks like switch from other languages, but it is stronger in two ways. First, match is an expression — the whole thing evaluates to a value, so you can bind its result directly with val. Second, each case holds a pattern, not just a single value: a constant, a captured variable with a condition attached (a guard), or the wildcard _ that matches anything.
val temp = 3
val advice = temp match {
case t if t >= 30 => "stay in the shade"
case t if t >= 10 => "perfect day"
case _ => "bring a jacket"
}
println(advice) // prints: bring a jacket
Each case reads case pattern => value. Cases are checked top to bottom and the first one that fits wins: its value becomes the value of the whole match. The guard case t if t >= 30 captures the number into t and matches only when the condition holds — Scala has no range pattern, so guards are how you say "30 or above".
The trap:
Unlike an if with no else, a match that fits no case does not quietly do nothing. Cover only scores of 80 and above, feed it a 55, and the program compiles without complaint — then crashes at runtime with this exact error:
scala.MatchError: 55 (of class java.lang.Integer)
at Main$.lesson(Main.scala:4)
at Main$.main(Main.scala:18)
at Main.main(Main.scala)
The message tells you which value slipped through every case: 55. The fix is a wildcard case, written case _ => ..., which matches anything the earlier cases didn't. End every match over an open-ended value with one, and a MatchError can never reach your users.
Matching a tuple:
Patterns can also take data apart. A tuple like (0, 5) packs two values together; a tuple pattern unpacks it and tests both slots at once:
val point = (0, 5)
val location = point match {
case (0, 0) => "origin"
case (0, y) => s"on the y-axis at $y"
case _ => "somewhere else"
}
(0, 0) matches one exact pair. (0, y) is the interesting one: the literal 0 must be equal, while the lowercase name y matches any second slot and captures it, so the right-hand side can use it. That double duty — test the shape, extract the parts — is why this feature is called pattern matching rather than just switching.
Assignment
Follow the Coding Tutorial to grade a score with guards, then locate a point with a tuple match:
- Declare
scoreas87and match it intograde: exactly100is"perfect",swiths >= 90is an"A",swiths >= 80is a"B", and anything else (_) is a"C". Print the grade. - Build
pointas the tuple(0, 5)and match it intolocation:(0, 0)is"origin",(0, y)iss"on the y-axis at $y", and_is"somewhere else". Print the location.
The exact expected output is:
grade = B
location = on the y-axis at 5
Hint
A guard goes between the captured name and the arrow: case s if s >= 90 => "A". If the program dies with scala.MatchError, you're missing the case _ wildcard at the bottom.
Free plan: 30 tutor messages. Premium is unlimited.