1. Overview
In this tutorial, we’ll explore the improvements made to match expressions within Scala 3. Match expressions have always been a powerful feature within Scala, and the improvements made in Scala 3 make it an even more versatile and helpful feature to use within our application code.
We’ll go through each new feature individually, explaining what each one can do, and go through a working example.
2. No Need for Braces
One change made to Scala 3 is that braces are no longer required in many cases, and indentation can be used instead. This applies to match expressions, meaning something like:
strOpt match {
case None => "Option is None"
case Some(str) => s"Option contains $str"
}
Now becomes:
strOpt match
case None => "Option is None"
case Some(str) => s"Option contains $str"
This makes our code look much cleaner and, when used appropriately, can make our code easier to read.
3. Nested match
The next improvement we’ll discuss is nested matches. This allows us to match* on the result of another *match:
strOpt match {
case None => "empty"
case Some(str) => str
} match {
case "empty" => "Option is None"
case string => s"Option contains $string"
}
First of all, we match on an Option[String] and return a String. We then match on the resulting String and return another String explaining its contents.
This simplified example is trivial, as the same result can be achieved within a single match expression. However, it clearly shows the use of the nested match construct.
4. Calling match After Period
We can now call match directly on the expression we want to match on, using .match:
strOpt.match
case None => true
case Some(_) => false
This change does not alter how the match executes or any other syntax. It’s simply an advantage of match being usable as an alphabetical operator.
5. Using match in if Statement
We can also use a match expression in conjunction with the new control structures available in Scala 3. This can be done using a match resulting in a Boolean as the condition of an if statement:
if strOpt.match
case None => true
case Some(_) => false
then "nothing"
else "A string"
This a fantastic way to leverage the new features of control structures in our code to make if statements on the results of match expressions more concise.
6. Type Ascription in match
The final change made to the match expression is a difference in how type ascriptions work within matches. In Scala 2, this would be valid:
strOpt: Option[String] match
case None => true
case Some(_) => false
Whereas now, in Scala 3, type ascriptions within a match expression need to be contained within parentheses:
(strOpt: Option[String]) match
case None => true
case Some(_) => false
This is something to be aware of if upgrading a codebase from Scala 2 to Scala 3.
7. Conclusion
In this article, we’ve explored the new features of match expressions that make them even more powerful in Scala 3 applications, such as nested matches and use in if conditions. We’re also aware of syntactical changes between Scala 2 and Scala 3 and are know of the changes that need to be made when upgrading Scala 2 code to Scala 3.
As always, the sample code used in this article is available over on GitHub.