3

Roland Kuhn 在这篇文章中已经回答了这个问题,然而,尽管有几条评论要求详细说明,但他并没有费心分享完整的答案。

这就是我想要做的:我有一个包装类case class Event[T](t: T),我将它的实例发送给 Akka 演员。在receive那个演员的方法中,然后我想区分Event[Int]and Event[String],由于类型擦除,这显然不是那么简单。

Roland Kuhn 在上述帖子中分享的是“只有一种方法可以做到”,即在消息中体现类型信息。所以我这样做了:

case class Event[T](t: T)(implicit val ct: ClassTag[T])

尽管被不同的人要求提供它,但罗兰库恩并没有说当时在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方法应该是什么样子。

4

2 回答 2

1

修复错误后Event takes type parameters

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!")
}

代码编译。不看 s 内部可以稍微简化一下ClassTag(当然,实现ClassTag#equals是要比较类):

import scala.reflect.{ClassTag, classTag}

def receive = {
  case e: Event[_] =>
    if (e.ct == ClassTag.Int) // or classTag[Int]
      println("Got an Event[Int]!")
    else if (e.ct == classTag[String])
      println("Got an Event[String]!")
    else
      println("Got some other Event!")
  case _ =>
    println("Got no Event at all!")
}
于 2016-11-13T20:14:29.653 回答
0

您还可以对嵌套类中的内部变量进行模式匹配,在这种情况下更简洁,您可以利用各种模式匹配技巧,甚至不需要 ClassTag:例如

case class Event[T](t: T)    

def receive = {
  case Event(t: Int) => 
    println("Int")
  case Event((_: Float | _: Double)) => 
    println("Floating Point")
  case Event(_) =>
    println("Other")
}
于 2016-11-25T06:12:23.187 回答