【发布时间】:2016-11-13 19:39:17
【问题描述】:
Roland Kuhn 在post 中已经回答了这个问题,然而,尽管有几位 cmets 询问细节,他并没有费心分享完整的答案。
这是我想要做的:我有一个包装类case class Event[T](t: T),我将其中的实例发送给 Akka 演员。在那个actor的receive方法中,然后我想区分Event[Int]和Event[String],由于类型擦除,这显然不是那么简单。
Roland Kuhn 在上述帖子中分享的是“只有一种方法可以做到”,即在消息中体现类型信息。所以我这样做了:
case class Event[T](t: T)(implicit val ct: ClassTag[T])
即使不同的人要求提供它,Roland Kuhn 也没有说明在 receive 方法中实际做什么。这是我尝试过的。
def receive = {
case e: Event =>
if (e.ct.runtimeClass == classOf[Int])
println("Got an Event[Int]!")
else if (e.ct.runtimeClass == classOf[String])
println("Got an Event[String]!")
else
println("Got some other Event!")
case _ =>
println("Got no Event at all!")
}
这是我能想到的最好的方法,因为很难将头绕在 Scala 的反射丛林中。但它没有编译:
value ct is not a member of Any
else if (e.ct.runtimeClass == classOf[String])
^
因此,我特意询问receive 方法应该是什么样子。
【问题讨论】:
-
这看起来对我来说是正确的(除了直接比较
ClassTag更简单:e.ct == ClassTag.Int和e.ct == classTag[String])。在错误消息中,您有s.ct,它不在代码中。 -
将其更改为
e.ct。我在这篇文章中将上面的代码简化为独立的。不过,我从真实代码中复制粘贴的错误消息。很好的收获,谢谢! -
您还需要修复
case e: Event[_]。在此之后,它编译:scastie.org/23724. -
发布它作为答案!也许您可以详细说明在这种情况下如何使用速记符号
Event[T : ClassTag]。另外,ClassTag.Int的String版本是什么?非常感谢,阿列克谢! -
已发布。在这种情况下,您不能使用
T: ClassTag(好吧,您可以,但它最终会更加冗长)。classTag[String]是String版本的ClassTag.Int。
标签: scala akka type-erasure scala-reflect