I tried to write a generic Actor and it can receive generic event
case class CreateEvent[T](t: T)
trait MyBaseActor[Type] extends Actor {
override def receive: Receive = {
case CreateEvent(t: Type) => ....
}
}
Then, I create an real actor
case class HasName(name: String)
class MyActor extends MyBaseActor[HasName]
And I expect MyActor
can handle message Create(HasName("hello")
as well. But when I compile code, I got this warning:
abstract type pattern Type is unchecked since it is eliminated by erasure
And my actor can't receive CreateEvent
also. Maybe I don't understand enough about Generic in scala, please help me explain why it not work and how can I fix it
It does not work because of type erasure. In runtime, any instance of CreateEvent
has type CreateEvent[Object]
so you can't match its generic type.
To work around it you can use ClassTag
:
trait MyBaseActor[Type] extends Actor {
val classTag: ClassTag[Type]
override def receive: Receive = {
case CreateEvent(t) if classTag.runtimeClass.isInstance(t) =>
val typedT: Type = t.asInstanceOf[Type]
....
}
}
class MyActor() extends MyBaseActor[HasName] {
override final val classTag: ClassTag[HasName] = implicitly[ClassTag[HasName]]
}