斯卡拉阿卡 - 仿制药输入接收处理程序(Scala Akka - generics type in

2019-09-30 08:00发布

我试图让我的头围绕什么是编写此实现最好的方式。 为了给你举例来说,这里是我的DAO处理程序代码看起来像

trait IDAOHandler[+T]  {
  def create[U <: AnyRef: Manifest](content: U): Try[String]
}

class MongoDAOHAndler extends IDAOHandler[+T]...

所以我创建的演员将处理我所有的持久性的任务,包括序列化的内容和更新的MongoDB数据库。

所以我用阿卡的诀窍就在于在接收方法,如何处理泛型类型参数。 虽然我的演员代码是不通用的,但它要接收邮件将是通用型和createDAO基于内容类型,我打算到适当的DAO处理器(描述aboe),并调用方法。

case class createDAO[T](content: T) (implicit val metaInfo:TypeTag[T])

class CDAOActor(daofactory: DAOFactory) extends BaseActor {
  def wrappedReceive = {
    case x: createDAO[_] => pmatch(x)
  }

  def pmatch[A](c: createDAO[A]) {
     //getting dao handler which will not work because it needs manifest
  }
}

让我知道,如果有任何其他的方式来重新写这个实现。

Answer 1:

你可能已经知道这一点,但有点背景只是要确定:在斯卡拉(和Java),我们有所谓类型擦除,这意味着参数类型被用来在编译时验证代码的正确性,但随后删除(“不给运行成本”, http://docs.oracle.com/javase/tutorial/java/generics/erasure.html )。 因此,参数类型已经被擦除运行时模式匹配情况。

好消息是,你可以让Scala编译器通过保持擦除型TypeTag就像你在你的情况类或已经做了ClassTag其中包含的信息较少,而且还使擦除类型。 你可以从该方法擦除型.erasure.runtimeClass在斯卡拉2.11),这将返回的Java类T类型。 你仍然不会能够使用它作为一种方法调用时,再次发生编译时的类型参数,现在你正在寻找该类型在运行,但你可以做的是用的if / else或在运行时比较这类型模式匹配。

因此,例如,你可以实现,需要一个对你daofactory的方法Class[_]参数,并返回一个DAO实例为类。 在pmatch你会然后采取擦除式出的标签,并传递给它。

下面是一些有关的标签,他们为什么存在以及它们是如何工作的详细信息: http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html



Answer 2:

我花了一点不同的方式,一种调度模式,所以这里是修改后的代码

trait IDAOProcess 
{
  def process(daofactory:IDAOFactory,sender:ActorRef) 
}

case class createDAO[T <: AnyRef : Manifest](content:T) (implicit val metaInfo:TypeTag[T]) extends IDAOProcess
{
  def process(daofactory:IDAOFactory,sender:ActorRef)
  {
    for ( handler <- daofactory.getDAO[T] ) 
    {
      handler.create(content)
    }
  }
}

class DAOActor(daofactory:IDAOFactory) extends BaseActor  
{
  def wrappedReceive =
  {
    case x:IDAOProcess => 
      {
        x.process(daofactory,sender)
      }
  }
}


文章来源: Scala Akka - generics type in receive handler
标签: scala akka