在运行时检查Scala类

时间:2015-04-02 23:46:31

标签: scala abstract-type

我有这个用例我无法解决。 我想到了一个消息传递编程的环境。 事物和环境有两个主要概念: 事情就像现实世界的东西,他们可以是被动的或主动的,他们可以发送和接收消息。环境使事物之间的通信成为可能。 我提出了这个解决方案:

/ **** Thing.scala **** /

abstract class Thing(environment : Environment){
  val uniqueName : String
  require(environment != null)
}

/ **** ActiveThing.scala **** /

trait ActiveThing extends Thing {
  environment.register(this)
  type inputType
  type outputType
  def receiveMessage(message : Message[inputType]) : outputType
  def canReceiveMessage(subject : String) : Boolean
}    

/ **** Environment.scala **** /

trait Environment {
  private var _passiveThings = List[PassiveThing]()
  private var _activeThings = List[ActiveThing]()

  def activeThings = _activeThings.toSeq
  def passiveThings = _passiveThings.toSeq
  def register(p : PassiveThing) = _passiveThings +:= p
  def register(a : ActiveThing)  = _activeThings +:= a
  def unicastRequest[T,K](from : String, message : Message[T], to : String) : K
}

/ **** Message.scala **** /

case class Message[T](subject : String, body : T)

但是当我尝试实际实现时:

/ **** EchoActiveThing.scala **** /

class EchoActiveThing(implicit inj: Injector) extends Thing()(inj) with ActiveThing {
  type inputType = String
  type outputType = String
  val uniqueName : String = "Echo"
  def receiveMessage(message : Message[inputType]) : outputType = {
    message.body
  }
  def canReceiveMessage(subject : String) : Boolean = {
    true
  }
}

/ **** BasicEnvironment.scala **** /

class BasicEnvironment extends Environment {
  def unicastRequest[T,K](from : String, message : Message[T], to : String) : K = {
     activeThings.filter{ x => 
       x.inputType == T &&
       x.outputType == K &&
       x.canReceiveMessage(message) &&
       activeThings.contains(to.uniqueName)
     }
   }
}

但它没有编译。我想我没有以正确的方式解决问题! 谢谢

1 个答案:

答案 0 :(得分:1)

x.inputType是一种类型投影,而不是变量。它无法与==进行比较,这就是代码无法编译的原因。要比较运行时的类型,可以使用TypeTag[T]

case class Holder[T](t: T)

def areEqualTypes[A, B](a: Holder[A], b: Holder[B])
                       (implicit tagA: TypeTag[A], tagB: TypeTag[B]) = {
  tagA == tagB
}

val (h1, h2, h3) = (Holder("Foo"), Holder("Bar"), Holder(5))
println(areEqualTypes(h1, h1)) //true
println(areEqualTypes(h1, h2)) //true
println(areEqualTypes(h1, h3)) //false

在示例中,类型标记与函数参数一起隐式传递。这次您可以使用==,因为tagAtagBTypeTag[A]TypeTag[B]类的实例。

相关问题