1

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

khacsinhcs
  • 179
  • 1
  • 16

1 Answers1

0

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]]
}
Aleksey Isachenkov
  • 1,230
  • 6
  • 16