I have read that case classes can be used with pattern matching. But, I am able to use a regular class with pattern matching as well. This question gives a regular scala perspective. I want it both from scala as well as akka perspective for this specific code. For example:
Actor class:
class TestActor extends Actor {
def receive={
case One(num)=>println("One "+num)
case t:Two=>println("Two "+t.num)
case _=>println("Another")
}
}
object TestActor{
case class One(num:Int)
}
Class Two:
class Two(var num:Int){ }
Main:
object Main2 extends App{
val system=ActorSystem("t")
val testActor=system.actorOf(Props[TestActor],"test")
val t=new Two(200)
val o=TestActor.One(100)
testActor!o
testActor!t
}
Output is:
One 100
Two 200
I know I am missing something here, probably in my understanding of pattern matching. Can someone help me out?
As you've noticed, the main difference with case classes in Akka is the ability to use their extractors (unapply methods) when matching (other than the usual features you get our of case classes, such as an implementation for
hashCode
,equals
, and working with them as a product type).With a larger example, you can see how this plays out nice. For example, assume you're using Akka-HTTP client to make HTTP requests to a third party service, and you want to operate differently if you get a
StatusCode.OK
, or any other status code. BecauseHttpResponse
provides anunapply
method, you can do:Instead of:
When your logic becomes more complex, extracting only the values you want can be very helpful and less verbose. In our codebase we have something more complex with multiple values, something like:
Of course, you can always create an
unapply
method in a companion object yourself and get the same semantics of a case class yourself, but you usually don't want to be writing that boilerplate, allowing the compiler to do it for you.To sum up, using
case class
as your data container in Akka eases the work with pattern matching, which is often what you do when implementing areceive
method.