Switch Cases and Pattern Matching in Scala
November 27, 2019 Leave a comment
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 }
Recent Comments