November 27, 2019
by Niranjan Tallapalli
In scala switch is enabled via Pattern Matching (PM) and its much more powerful than other languages often referred as “Switch on Steroids”
Some of the properties of switch case are
1. Cases are match in the same order they are written
2. If no cases match it will result in MatchError, make sure all the cases are covered with wildcard
3. Type of Pattern Matching expression is the unified type of all the types from all the cases
4. PM works really well with case classes
Simple switch statement
val random = new Random
val x = random.nextInt(10)
val description = x match {
case 1 => "First element"
case 2 => "Second element"
case 3 => "Third element"
case _ => "Default element" // this is a WILDCARD which matches for all other patterns
}
println(description)
Interesting property of Pattern Matching is that it can decompose values especially when used with case classes.
sealed class Animal
case class Dog(breed: String) extends Animal
case class Parrot(greeting: String) extends Animal
val animal: Animal = Dog("terra Nova")
animal match {
case Dog(breed) => println(s"Matched dog of type $breed breed")
}
Different scenarios/ways we can use switch statement
// 1. Constants
val x: Any = "Scala"
val constants: Any = x match {
case 1 => "a number"
case "Scala" => "The scala"
case true => "The Truth"
case a02AllThePatterns => "A singleton Object"
}
println(constants)
// 2. Match Anything
// 2.1 Wildcard
val matchAnything = x match {
case _ => "I will match everything"
}
println(matchAnything)
// 2.2 variable
val matchAVariable = x match {
case something => s"I have found $something"
}
println(matchAVariable)
// 3 tuples
val aTuple = (1, 2)
val matchATuple = aTuple match {
case (1, 1) => "Found tuple"
case (something, 2) => s"I have found tuple with $something"
}
println(matchATuple)
// PMs can be nested
val nestedTuple = (1, (2, 3))
val matchANestedTuple = nestedTuple match {
case (_, (2, v)) =>
}
println(matchANestedTuple)
// 4. case classes - constructor pattern
// PMs can be nested with CCs as well
val aList: GenericList[Int] = new Cons(1, new Cons(2, Empty))
val matchAList = aList match {
case Empty =>
case Cons(h, t) =>
case Cons(h, Cons(subHead, subTail)) => // nested classes
}
// 5 - List Patterns
val aStandardList = List(1, 2, 3, 4, 5)
val matchAStandardList = aStandardList match {
case List(1, _, _, _) => // extractor concept in advanced training
case List(1, _*) => // List of arbitrary length in advanced training
case 1 :: List(_) => // infix pattern
case List(1, 2, 3) :+ 42 => // infix pattern
}
// 6. Type specifiers
val unknown: Any = 2
val matchAUnknown = unknown match {
case list: List[Int] => // explicit type specifier
case _ =>
}
// 7. Name Binding
val MatchANameBinding = aList match {
case nonEmptyList @ Cons(_, _) =>
// name binding allows us to use the name later
// Its like variables but we can name entire pattern here and its very powerful
case Cons(1, rest @ Cons(2, _)) =>
// Name Binding is also possible in nested patterns
}
// 8. Multi Patterns
val matchAMultiPattern = aList match {
case Empty | Cons(0, _) => // Matches multiple patterns with pipe operator
}
// 9. if guards
val matchASpecialElement = aList match {
case Cons(specialElement, _) if specialElement % 2 == 0 =>
// if guard on a variable
}
Like this:
Like Loading...
Recent Comments