[英]Scala class check at runtime
I have this use case i cannot solve. 我有这个用例,我无法解决。 I thought of an environment for message passing programming. 我想到了用于消息传递编程的环境。 There are two main concepts, Things and Environment: Things are like real world Things they can be passive or active and they can send and receive messages. 有两个主要概念,事物和环境:事物就像现实世界一样,事物可以是被动的也可以是主动的,并且可以发送和接收消息。 The environment enables the communication between Things. 环境使事物之间能够通信。 I came up with this solution: 我想出了这个解决方案:
/**** Thing.scala ****/ / **** Thing.scala **** /
abstract class Thing(environment : Environment){
val uniqueName : String
require(environment != null)
}
/**** ActiveThing.scala ****/ / **** 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 ****/ / **** 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 ****/ / **** Message.scala **** /
case class Message[T](subject : String, body : T)
But when i try to actually implement: 但是当我尝试实际实现时:
/**** EchoActiveThing.scala ****/ / **** 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 ****/ / **** 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)
}
}
}
But it doensn't compile. 但是它不会编译。 I think I'm not approaching the problem in the right way! 我认为我没有以正确的方式解决问题! Thank you 谢谢
x.inputType
is a type projection, not a variable. x.inputType
是类型投影,而不是变量。 It cannot be compared with ==
and that's why code does not compile. 它不能与==
进行比较,这就是代码无法编译的原因。 To compare types in runtime you can use TypeTag[T]
要在运行时比较类型,可以使用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
In the example type tags are implicitly passed alongside with function parameters. 在示例中,类型标记与函数参数一起隐式传递。 This time you can use ==
because tagA
and tagB
are instances of TypeTag[A]
and TypeTag[B]
classes. 这次您可以使用==
因为tagA
和tagB
是TypeTag[A]
和TypeTag[B]
类的实例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.