在akka中保存类型信息 [英] Preserving type information in akka Receive

查看:70
本文介绍了在akka中保存类型信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以在消息处理程序的部分函数中保留类型信息?

Is it possible to preserve type information in message handler partial function?

我有部分函数eventHandler通过某些特定参数与事件匹配:

I have partial function eventHandler that matches event by some specific parameters:

  def eventHandler: Receive = {
    case event: Event ⇒
        ...
        val matchingReactions = projectConfiguration.reactions.filter(reaction ⇒ reaction.eventSelector.matches(event))

其中的match方法会针对通过反射设置的规则:

Where matches method validates event against a set of rules through reflection:

case class EventSelector(ops: List[FieldEventSelectorOp]) {
  def matches[T <: Event](event: T)(implicit tag: ru.TypeTag[T], classtag: ClassTag[T]): Boolean = {
    ops.map {
      op ⇒ op.matches(event)
    }.reduceLeft(_ & _)
  }
}

case class FieldEventSelectorOp(field: String, operation: Symbol, value: Any) { 
  def matches[T <: Event](event: T)(implicit tag: ru.TypeTag[T], classtag: ClassTag[T]): Boolean = {
...
}

因此,当我检查match方法中的TypeTag是什么时,它仅返回事件,而不返回事件的子类-如何使它传递完整的类型信息?

So, when I check what is the TypeTag in matches method it returns just Event, not subclass of event - how do I make it pass full type information?

更新:

事件的案例类层次结构:

case class hierarchy for events:

trait Event {
  def eventType: String
  def eventName: String = this.getClass.getSimpleName
}

trait VCSEvent extends Event {
  def eventType: String = "VCS"
}

case class BranchAdded(branch: String) extends VCSEvent
case class TagAdded(tag: String, commitId: String) extends VCSEvent

具体匹配项:

case class FieldEventSelectorOp(field: String, operation: Symbol, value: Any) extends EventSelectorOp {
  def matches[T <: Event](event: T)(implicit tag: ru.TypeTag[T], classtag: ClassTag[T]): Boolean = {
    val mirror = ru.runtimeMirror(event.getClass.getClassLoader)
    val memberSymbol = tag.tpe.member(ru.newTermName(field))

    if (memberSymbol.name.decoded.equals("<none>"))
      return false

    val fieldValue = if (memberSymbol.isMethod) {
      mirror.reflect(event).reflectMethod(memberSymbol.asMethod).apply()
    } else {
      mirror.reflect(event).reflectField(memberSymbol.asTerm).get
    }

    operation match {
      case 'eq ⇒ fieldValue.equals(value)
      case _   ⇒ false
    }
  }
}


推荐答案

TypeTags描述仅在编译时存在的类型:在运行时,这些类型将被删除,您可以通过 event.getClass 。如果要将通用类型信息传递给actor,则只有一种方法:在消息内。

TypeTags describe types which exist only at compile time: at runtime the types are erased, all you get is available via event.getClass. If you want to pass generic type information into the actor, then there is exactly one way to do it: within the message.

trait Event[T] {
  def typeTag: ru.TypeTag[T]
  ...
}

case class MyEvent[T](...)(implicit val typeTag: ru.TypeTag[T])

这篇关于在akka中保存类型信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆