我想知道是否有可能在演员中收到一个元组而没有收到此警告:
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)
}
我错过了什么吗?
答案 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