加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

(也未经过测试!)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读