scala - 在 akka Receive 中保存类型信息

标签 scala reflection akka

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

我有部分函数 eventHandler,它通过一些特定参数匹配事件:

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

where matches 方法通过反射根据一组规则验证事件:

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 = {
...
}

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

更新:

事件的案例类层次结构:

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 获得。如果您想将通用类型信息传递给参与者,那么只有一种方法可以做到:在消息中。

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

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

关于scala - 在 akka Receive 中保存类型信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18819924/

相关文章:

java - 执行 io 时 akka jvm 线程与 os 线程

scala - 将 [String,Object] 从数据库(或键值存储)映射到无形可扩展记录

java:在运行时在子类中强制执行无参数构造函数

postgresql - 在表定义时检查字符串是否在列表中

c# - 字段的实际性能与属性

c# - 通过 Linq 表达式指定 MethodInfo 的面向 future 的方法

scala - 将回调方法实现转换为 akka 流 Source

scala - 带有可变参数的案例类的隐式 jsonFormat

scala - 为什么 akka Actor 没有 postStart 方法?

scala - scala-2.8 和 scalacheck : Prop has wrong version 错误