我试图让我的头围绕什么是编写此实现最好的方式。 为了给你举例来说,这里是我的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
}
}
让我知道,如果有任何其他的方式来重新写这个实现。
你可能已经知道这一点,但有点背景只是要确定:在斯卡拉(和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
我花了一点不同的方式,一种调度模式,所以这里是修改后的代码
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)
}
}
}