I'm wondering how can I use multiple type pattern matching. I have:
abstract class MyAbstract case class MyFirst extends MyAbstract case class MySecond extends MyAbstract case class MyThird extends MyAbstract // shouldn't be matched and shouldn't call doSomething() val x: MyAbstract = MyFirst x match { case a: MyFirst => doSomething() case b: MySecond => doSomething() case _ => doSomethingElse() }
So I'd like to write something like:
x match { case a @ (MyFirst | MySecond) => doSomething() case _ => doSomethingElse() }
I saw similar construction in some tutorial, but it gives me error:
pattern type is incompatible with expected type; [error] found : object MyFirst [error] required: MyAbstract
So is there a way to define few different types in on case clause? I think it would make code prettier. As if I will have 5 of them, I will write same code 5 times (calling doSomething()).
Thanks in advance!
Pattern matching is a way of checking the given sequence of tokens for the presence of the specific pattern. It is the most widely used feature in Scala. It is a technique for checking a value against a pattern. It is similar to the switch statement of Java and C.
Using if expressions in case statements First, another example of how to match ranges of numbers: i match { case a if 0 to 9 contains a => println("0-9 range: " + a) case b if 10 to 19 contains b => println("10-19 range: " + b) case c if 20 to 29 contains c => println("20-29 range: " + c) case _ => println("Hmmm...") }
case _ => does not check for the type, so it would match anything (similar to default in Java). case _ : ByteType matches only an instance of ByteType . It is the same like case x : ByteType , just without binding the casted matched object to a name x .
Case classes are Scala's way to allow pattern matching on objects without requiring a large amount of boilerplate. In the common case, all you need to do is add a single case keyword to each class that you want to be pattern matchable.
You are missing the parenthesis for your case classes. Case classes without parameter lists are deprecated.
Try this:
abstract class MyAbstract case class MyFirst() extends MyAbstract case class MySecond() extends MyAbstract val x: MyAbstract = MyFirst() x match { case aOrB @ (MyFirst() | MySecond()) => doSomething(aOrB) case _ => doSomethingElse() }
If you have too many params for your case classes and don't like having to write long Foo(_,_,..)
patterns, then maybe:
x match { case aOrB @ (_:MyFirst | _:MySecond) => doSomething(aOrB) case _ => doSomethingElse() }
Or just:
x match { case _:MyFirst | _:MySecond => doSomething(x) // just use x instead of aOrB case _ => doSomethingElse(x) }
But perhaps you just wanted singleton case objects?
abstract class MyAbstract case object MyFirst extends MyAbstract case object MySecond extends MyAbstract val x: MyAbstract = MyFirst x match { case aOrB @ (MyFirst | MySecond) => doSomething() case _ => doSomethingElse() }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With