通用类型

时间:2018-01-10 18:48:33

标签: scala generics apache-kafka akka akka-stream

我有一个像这样定义的Actor实例:

class KafkaPublisher[T <: KafkaMessage] extends Actor {

  override final def receive = {
    case ProducerStreamActivated(_, stream: SourceQueueWithComplete[T]) =>
      context.become(active(stream))

    case other => println("KafkaPublisher got some unknown message while producing: " + other)
  }

  def active(stream: SourceQueueWithComplete[T]): Receive = super.receive orElse {
    case msg: T =>
      stream.offer(msg)

    case other => println("KafkaPublisher got the unknown message while producing: " + other)
  }
}
object KafkaPublisher {

  def props[T <: KafkaMessage](implicit tag: ClassTag[T]) = Props(new KafkaPublisher[T])
}

KafkaMessage是标记特征,我想发布给Kafka的每条消息都会扩展这个标记特征。我有一个主管Actor,实际上将根据Kafka消息的类型创建此KafkaPublisher Actor的实例。例如。,

case class MeterData(id: String, meterReadings: Map[DateTime, String]) extends KafkaMessage

所以在我的SupervisorActor中,我创建了一个PublisherActor的实例,如下所示:

def actorFor(props: Props, actorName: String) = context.actorOf(props, actorName)
val actorRef = actorFor(KafkaPublisher.props[MeterData], "meter-data-actor")

类似地,我为给定的KafkaMessage类型创建相应的Akka流流。

所以我的问题是,考虑到我定义了通用模式匹配,这个KafkaPublisher actor模式是否会匹配MeterData。我的道具方法中的ClassTag是否足以让我能够超越类型擦除?建议?

1 个答案:

答案 0 :(得分:2)

当范围内存在隐式T时,泛型类型ClassTag[T]上的模式匹配应该有效。因此,在ClassTag

中提供并存储KafkaPublisher就足够了
import scala.reflect.ClassTag

class KafkaPublisher[T <: KafkaMessage : ClassTag] {
  /* ... */
}

object KafkaPublisher {
  def props[T <: KafkaMessage : ClassTag] = Props(new KafkaPublisher[T])
}

如果T呼叫网站上的props类型具体,或者它是通用的,但那里有隐式ClassTag[T],那么您只需拨打{{1像往常一样:props