是否有可能在没有警告的情况下在演员内部接收元组"通过擦除消除"

时间:2016-06-19 11:03:25

标签: scala tuples akka actor

我想知道是否有可能在演员中收到一个元组而没有收到此警告:

non-variable type argument Long in type pattern (Long, Int) is unchecked since it is eliminated by erasure

虽然代码似乎有效且有效:

override def receive: Receive = {
  case tuple: (Long, DateTime) => sendPlace(tuple._1, tuple._2)
}

我错过了什么吗?

2 个答案:

答案 0 :(得分:3)

书写

case (id: Long, time: DateTime) => sendPlace(id, time)

也会避免未经检查的演员表,但Łukasz是对的:你应该为此目的定义一个案例类。

  

由于两个应用程序在一起通信,因此我不允许将案例类定义为两次

当然你不应该定义两次。在两个应用程序所依赖的库中定义一次。这样1)你明确了应用程序通信的位置; 2)如果您需要更改消息类型(例如添加其他字段,或更改其中一个字段的类型),您将不太可能忘记更改其中一个。

  

请你解释为什么我不接受收到消息的演员的上下文中的警告?

你这样做:

val x: Any = ("a", "b")

x match {
  case tuple: (Long, DateTime) => 
    println("shouldn't match, but does")
}

答案 1 :(得分:2)

元组是通用类型,例如Tuple2[T1, T2]并且在JVM中,这些类型参数将被擦除,并且不会出现在运行时中。这个主题在网上有很多。

您的代码有效,但只有在检查消息是否与模式匹配的情况下,如果消息是Tuple2,而不是内部类型。如果此演员得到另一个Tuple2,说(String, String),在尝试将String转换为Long时,会尝试将第一个元素传递给{{1}方法。

例如以下

sendPlace

第二个模式无法访问,它永远不会匹配,因为任何override def receive: Receive = { case tuple: (Long, DateTime) => sendPlace(tuple._1, tuple._2) case tuple: (Int, Int) => sender ! (tuple._1 + tuple._2) } 都将匹配第一个模式,如果类型错误则抛出异常。

通常,您应该为消息创建案例类。这对于消息及其成员都有一个有意义的名称的好处,元组只是说它的类型。您应该定义actor在其伴随对象中可以处理的消息。

Tuple2