This question has kind of been answered by Roland Kuhn in this post, however, despite several comments asking for detail, he didn't bother to share the complete answer.
Here's what I want to do: I have a wrapper class case class Event[T](t: T)
of which I send instances to an Akka actor. In the receive
method of that actor, I then want to distinguish between Event[Int]
and Event[String]
, which obviously isn't so simple due to type erasure.
What Roland Kuhn shares in the mentioned post is that "there is exactly one way to do it", that is, embodying the type information within the message. So I did this:
case class Event[T](t: T)(implicit val ct: ClassTag[T])
Even though asked by different people to provide it, Roland Kuhn does not say what to actually do within the receive
method then. Here's what I tried.
def receive = {
case e: Event =>
if (e.ct.runtimeClass == classOf[Int])
println("Got an Event[Int]!")
else if (e.ct.runtimeClass == classOf[String])
println("Got an Event[String]!")
else
println("Got some other Event!")
case _ =>
println("Got no Event at all!")
}
This is the best I could come up with as it's hard to wrap one's head around Scala's reflection jungle. It's not compiling, though:
value ct is not a member of Any
else if (e.ct.runtimeClass == classOf[String])
^
Thus, I am asking specifically about what the receive
method should look like.
After fixing the error Event takes type parameters
:
def receive = {
case e: Event[_] =>
if (e.ct.runtimeClass == classOf[Int])
println("Got an Event[Int]!")
else if (e.ct.runtimeClass == classOf[String])
println("Got an Event[String]!")
else
println("Got some other Event!")
case _ =>
println("Got no Event at all!")
}
the code compiles. It can be slightly simplified by not looking inside the ClassTag
s (of course, the implementation of ClassTag#equals
is going to compare the classes):
import scala.reflect.{ClassTag, classTag}
def receive = {
case e: Event[_] =>
if (e.ct == ClassTag.Int) // or classTag[Int]
println("Got an Event[Int]!")
else if (e.ct == classTag[String])
println("Got an Event[String]!")
else
println("Got some other Event!")
case _ =>
println("Got no Event at all!")
}