我如何解决Akka接收方法上的类型擦除 [英] How do I get around type erasure on Akka receive method

查看:129
本文介绍了我如何解决Akka接收方法上的类型擦除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Scala 2.10中使用蛋糕模式,根据一些业务逻辑将所需的特征注入我的演员:

I'm using cake pattern in Scala 2.10 to inject required trait to my actor acording to some bussiness logic:

我有几种类型的f事件:

I have several types f Events:

 sealed abstract class Event(val timeStamp:Long)
  case class StudentEvent(override val timeStamp:Long, studentId:Long)  extends Event(timeStamp:Long)
  case class TeacherEvent(override val timeStamp:Long, teacherIdId:Long)  extends Event(timeStamp:Long)

现在我具有为每种事件实现动作的特征:

Now I have traits which implement action for each type of event:

摘要:

trait Action[T <: Event] {   
  def act[T](event:T):Unit
}

还有两个暗示:

trait StudentAction extends Action[StudentEvent]{
  override def act[StudentEvent](event:StudentEvent):Unit = println(event)
}

trait TeacherAction extends Action[TeacherEvent]{
  override def act[TeacherEvent](event:TeacherEvent):Unit = println(event)
}

现在我的演员:

class ActionActor[T <: Event] extends Actor{
  self:Action[T]=>

  override def receive= {
    case msg: T => act(msg)
    case _ => println("Unknown Type")
  }
}

我需要注入这样的特征:

And I inject required trait this way:

 val actionActor =  system.actorOf(Props(new ActionActor[StudentEvent] with StudentAction))
 actionActor ! StudentEvent(1111L,222L)

在编译时出现错误:

Warning:(14, 14) abstract type pattern T is unchecked since it is eliminated by erasure
    case msg:T => act(msg)
         ^

我知道我需要使用TypeTag,但是我无法理解我该怎么办。

I know that somehow I need to use TypeTag, but I failed to understand how can I do it.

请帮助。

更新:

实际上,我有10种类型的事件,这些事件是我需要处理的事件的扩展。

In reality, I have 10 type of events which extends from Event that I need to handle.

我想针对每个事件在单独的特征中实现业务逻辑,因为混合所有10个事件处理函数将给我几百(如果不是几千)行代码。

I want to implement business logic for each event in separate trait, because because mixing all 10 event handler functions will give me several hundreds(if not thousands) lines of code.

我不想为每个事件创建不同的Actor类型。例如:

I don't want to create different Actor types for each event. For example:

class Event1Actor extend Actor{
  def receive ={
     case Event1(e) => //event1 Business Logic
   }
}

class Event2Actor extend Actor{
  def receive ={
     case Event2(e) => //event2 Business Logic
   }
}  

以及相同的Event3Actor,Event4Actor等等。

and the same Event3Actor, Event4Actor,etc....

对我来说,这样的代码似乎很丑陋,因为我需要在每个Actor中实现业务逻辑。

Such code seems ugly to me, because I need to implement business Logic inside each Actor.

我正在寻找一种基于设计模式的通用解决方案,例如策略模式。

I'm seeking for some kind generic solution based on design pattern, for example strategy pattern.

推荐答案

首先,我建议将您的事件定义为:

First, I would suggest defining your events as:

sealed trait Event { def timeStamp: Long }
case class StudentEvent(timeStamp: Long, studentId: Long)
  extends Event
case class TeacherEvent(timeStamp: Long, teacherId: Long)
  extends Event

这是代数数据类型的标准编码

This is the standard encoding for algebraic data types.

第二,您使用自定义类型的这项业务对我来说真的很令人困惑。当然,同一对象不应该既是演员又是动作?为什么不在这里使用合成而不是继承呢? (感觉就像您只是将Scala功能整合在一起。因此,这里的一般建议是:放慢速度。)

Second, this business where you're using a self-type seems really confusing to me. Surely the same object shouldn't be both an "actor" and an "action"? Why not use composition here instead of inheritance? (It kinda feels like you're just throwing Scala features together. So a general piece of advice here would be: slow down.)

但是要解决您的主要问题,我认为您从根本上走错了路。几乎在任何时候您都遇到了类型擦除和/或 TypeTag 的情况时,这表明您的设计存在缺陷,应该备份并重新考虑-除非您真的知道

But to address your main question, I think you're fundamentally on the wrong path. Almost any time you end up butting heads with type erasure and/or TypeTag, it's a sign that your design is flawed and you should back up and rethink — unless you realllllllly know what you're doing.

无论如何,您将无法使Akka附加 TypeTag 到您的消息。 Akka不能那样工作。 (已经进行了一系列努力来向 Akka添加类型化的演员或类型化的频道,您可能会查找这些内容,但是除非您完全确定并非如此,否则在您的用例中这可能是过大的。)

In any case, you're not going to be able to get Akka to attach a TypeTag to your messages. Akka just doesn't work that way. (There have been a series of efforts to add "typed actors" or "typed channels" to Akka, and you might look those up, but it's probably overkill in your use case unless you're realllllly sure it isn't.)

您要在此处解决的基础架构问题是什么?促使这种设计的原因是什么?

What is the underlying architectural problem that you're trying to solve here? What motivated this design?

查看在Akka的Scala中构成特征行为接收方法,看起来确实很相似,并且在消化之后,我认为您可以更好地决定下一步要做什么。

Check out Composing trait behavior in Scala in an Akka receive method, it seems really similar, and after digesting it, I think you'll be in a better position to decide what to do next.

这篇关于我如何解决Akka接收方法上的类型擦除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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