“共享”参数化类型

时间:2016-10-27 14:37:40

标签: scala

我知道有一个简单的解决方案。但我想不出来。

我有一个恰好是Actor的通用队列,它包含的内容是类型参数化的。我需要一个案例类添加消息来将数据发送到队列,这应该强制执行相同的类型。

我们可以这样做:

类Queue [A]扩展了Actor {   案例类添加[A](项目:Seq [A])   ...

这个问题是我们只能从Queue实例创建Add实例,只知道ActorRef的客户端不会有这样的实例。

如果我们将Add添加到Queue之外,那么问题就会消失,但当然编译器不知道Add的类型参数和Queue的类型参数是否以任何方式相关。需要使用类型转换来组合两者的集合。

有没有一种简单的方法告诉编译器两个不相关的类中的类型参数是否相关?

1 个答案:

答案 0 :(得分:0)

当您在Add[_]演员中收到Queue[A]消息时,您需要进行演员/类型检查,因为发件人不知道演员的类型,所以不能强制他们发送了Add[A]而不是Add[B]

由于type erasure

,这会很尴尬

将消息作为类型依赖类放在actor中也很尴尬,因为你会发现它很难构建。

可以做到,但我认为你最好简化设计。你走了:

import Queue.Add
import akka.actor.{Actor, ActorSystem, Props}
import scala.reflect.runtime.universe._

class Queue[A]()(implicit tt: TypeTag[A]) extends Actor {

  override def receive = {
    case a@ Add(items) if a.tpe.tpe <:< typeOf[A] =>
      println("added: " + items)

    case other =>
      println("bad message: " + other)
  }
}

object Queue {
  case class Add[A](
    items: List[A])(
    implicit val tpe: TypeTag[A])
}

object Main {
  def main(args: Array[String]): Unit = {

    val system = ActorSystem()

    val stringQueue = system.actorOf(Props(new Queue[String]()))

    stringQueue ! Add(List("a","b"))
    stringQueue ! Add(List(1,2,3))
  }
}