I have something like this:
class ProbeActor extends Actor {
case class Probe(messageKey: String)
def receiveProbe: Receive = {
case Probe(probeKey) => println("Good probe: "+probeKey)
case x => println("Bad probe: "+ x)
}
final override def receive = receiveProbe orElse receiveOther
def receiveOther: Receive = {
case _ => println("Other")
}
}
and I call it like this:
class Prober extends ProbeActor {
val definite = ActorSystem("ProbeTest").actorOf(Props[ProbeActor], name = "probed")
implicit val timeout = Timeout(5 second)
val future = definite ? Probe("key")
}
I expect the text "Good probe: key"
should be printed, but I get "Bad probe: Probe(key)"
.
Note: If I put the Probe
case class outside, then it works fine.
After searching more, I found an answer on scala-lang.org:
I think the underlying misconception is about the identity of nested class types.
In
class A { class B }
each new instance of class A x creates a new type x.B. And if you do the plain pattern match inside of A you are referring to the specific instance of the type B this.B.
A way to pattern-match on Probe
without moving it outside the class is
case probe: ProbeActor#Probe => println("Good probe: "+probe.messageKey)
Of course, moving it outside (e.g. to the companion object) is the better solution; particularly in Akka, as Archeg mentions, to avoid the direct reference to the actor.
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