Scala Akka-接收处理程序中的泛型类型 [英] Scala Akka - generics type in receive handler

查看:83
本文介绍了Scala Akka-接收处理程序中的泛型类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力弄清编写此实现的最佳方法。举个例子,这是我的DAO处理程序代码

I am trying to get my head around on what is best way to code this implementation. To give you example, here is my DAO handler code looks like

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

class MongoDAOHAndler extends IDAOHandler[+T]...

因此,我正在创建一个actor,它将处理我的所有持久性任务,包括序列化内容和更新MongoDB数据库。

So I am creating actor that will handle all my persistence task that includes serializing the content and updating MongoDB database.

所以我正在使用akka,窍门是在receive方法中,我该如何处理泛型类型参数。即使我的actor代码不是通用的,但是它将接收的消息将是通用类型,并且基于createDAO中的内容类型,我正计划获取适当的DAO处理程序(从前描述)并调用该方法。

So I am using akka and the trick is in receive method, how do i handle generics type parameter. Even though my actor code is non-generic, but the messages it is going to receive will be generic type and based on content type in createDAO I was planning to get appropriate DAO handler (described aboe) and invoke the method.

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
  }
}

让我知道是否还有其他重写方法此实现。

Let me know if there are any other ways to re-write this implementation.

推荐答案

您可能已经知道这一点,但是要确保有一点背景知识:在Scala(和Java)中,我们有称为类型擦除,这意味着参数类型用于在编译时验证代码的正确性,但随后将其删除(并且不提供运行时成本, http://docs.oracle.com/javase/tutorial/java/generics/erasure.html )。模式匹配发生在运行时,因此参数类型已经被擦除。

You might already know this, but a little background just to be sure: In Scala (and Java) we have what is called type erasure, this means that the parametric types are used to verify the correctness of the code during compile time but is then removed (and "does not give a runtime cost", http://docs.oracle.com/javase/tutorial/java/generics/erasure.html). Pattern matching happens during runtime so the parametric types are already erased.

好消息是,您可以使Scala编译器使用 TypeTag 就像您在case类中所做的一样,或者 ClassTag 包含较少的信息,但仍保留已擦除的类型。您可以从方法 .erasure (在Scala 2.11中为 .runtimeClass )中获取擦除的类型,该方法将返回Java类。 T 类型的。您仍然无法将其用作方法调用的类型参数,因为这再次发生在编译时,并且您现在正在运行时查看该类型,但是您可以做的是在运行时将这种类型与if / else或模式匹配。

The good news is that you can make the Scala compiler keep the erased type by using TypeTag like you have done in your case class or ClassTag which contains less information but also keeps the erased type. You can get the erased type from the method .erasure (.runtimeClass in Scala 2.11) which will return the Java Class of the T type. You still wont be able to use that as the type parameter for a method call as that again happens compile time and you are now looking at that type in runtime, but what you can do is to compare this type during runtime with if/else or patternmatching.

例如,您可以在daofactory上实现一个方法,该方法采用 Class [_] 参数,返回该类的DAO实例。在pmatch中,您然后将已删除的类型从标签中取出并传递给标签。

So for example you could implement a method on your daofactory that takes a Class[_] parameter and returns a DAO instance for that class. In pmatch you would then take the erased type out of the tag and pass on to it.

以下是有关标签,标签为何存在以及如何工作的更多信息:
http://docs.scala-lang.org/ overviews / reflection / typetags-manifests.html

Here is some more info about the tags, why they exist and how they work: http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html

这篇关于Scala Akka-接收处理程序中的泛型类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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