scala – 是否有可能克服akka接收中的类型擦除?
发布时间:2020-12-16 18:28:15 所属栏目:安全 来源:网络整理
导读:我有一个特征和实现akka actor,由于类型擦除无法正确区分传入消息的类型,因此第一种情况是匹配所有消息. 我正在使用scala 2.10.x,并且从阅读许多其他答案我知道可以使用TypeTag或ClassTag恢复特征内的类型信息,但我无法弄清楚如何应用它(如果可能的话)在akka
我有一个特征和实现akka actor,由于类型擦除无法正确区分传入消息的类型,因此第一种情况是匹配所有消息.
我正在使用scala 2.10.x,并且从阅读许多其他答案我知道可以使用TypeTag或ClassTag恢复特征内的类型信息,但我无法弄清楚如何应用它(如果可能的话)在akka内接收. 我(非常简化)的例子如下.是否可以正确匹配泛型类型? package com.ebay.box.canada.batch.jobs.siteMap import akka.actor.Actor import akka.actor.ActorSelection import akka.actor.Actor.Receive import scala.reflect.ClassTag trait MessageProcessor[A,B] { this: Actor => val destA: ActorSelection val destB: ActorSelection def processA(a: A): A def processB(a: B): B def receive: PartialFunction[Any,Unit] = { case a: A => destA ! processA(a) case b: B => destB ! processB(b) } } class StringIntProcessor(val destA: ActorSelection,val destB: ActorSelection) extends MessageProcessor[String,Int] with Actor { def processA(a: String) = { a + "1" } def processB(b: Int) = { b + 1 } } 解决方法
我不认为您可以在特征中获得TypeTag [A]或ClassTag [A] – 类型标签/类标签始终是方法调用的隐式参数列表的一部分.您可以使用隐式构造函数参数来使用抽象类:
import scala.reflect.runtime.universe._ abstract class MessageProcessor[A,B]()(implicit cta: ClassTag[A],ctb: ClassTag[B]) { def receive = { case a: Any if a.getClass() == cta.runtimeClass => process(a.asInstanceOf[A]) ... } ... } (未经测试!) 假设您可以更改发送消息的代码,我可以建议使用以下设计吗? MessageProcessor现在是一个类型类,因此您可以添加任意数量的消息类型.通过发送闭包作为消息,您可以将任意数量的上下文走私到呼叫站点. class MessageReceiver extends Actor { def receive = { case fn: Function0[Unit] => fn() } } trait MessageProcessor[A] { val dest: ActorSelection def process(a: A): A } object Processors { implicit object StringProcessor extends MessageProcessor[String] { val dest: ActorSelection = Wellknown.stringDest def process(a: String): String = a + "1" } implicit object IntProcessor extends MessageProcessor[Int] { val dest: ActorSelection = Wellknown.intDest def process(a: Int): Int = a + 1 } def sendMessage[A](msg: A)(implicit ev:[MessageProcessor[A]]): Unit = { val block: Function0[Unit] = { () => ev.dest ! ev.process(msg) } val msgDest = system.actorOf[Props[MessageReceiver]],"msgDest") msgDest ! block } } (也未经过测试!) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |