【发布时间】:2014-03-08 08:53:52
【问题描述】:
对于下面 Option[Entity] 的匹配,第三种情况需要是详尽的。为什么?
entitiesMap 是一个 var,其中包含一个不可变的 Map[UUID,Entity]。它在单个 Akka Actor 中进行访问和更新,以避免线程问题。下面是 receive 函数的摘录:
class WorldActor extends Actor {
var world: World = null
override def receive = {
case WorldSet(w) =>
world = w
// get that state and apply it to its entity
case s: State if (world != null) =>
val uuid = new UUID(s.getUuid().getL1(), s.getUuid().getL2())
world.entitiesMap.get(uuid) match {
case Some(ent) =>
// Update entity's state
ent.setEntityState(s)
case None =>
Log.error("World doesn't contain entity uuid: " + uuid)
case other =>
Log.error("Received unknown message: " + other)
}
case AddEntity(ent) if (world != null && ent != null) =>
if (!world.entitiesMap.contains(ent.uuid))
world.entitiesMap += ent.uuid -> ent
case RemoveEntity(ent) if (world != null && ent != null) =>
if (world.entitiesMap.contains(ent.uuid))
world.entitiesMap -= ent.uuid
case other => // ignore
}
}
class World {
// Entity container
var entitiesMap = Map[UUID,Entity]()
}
上面的代码时不时会报告:
Received unknown message: None
为什么上面的 case None 模式没有捕捉到它?
编辑
我发现当消息 State 出现在消息 AddEntity 之前,即 entitiesMap 还没有包含 实体由消息状态引用。
01:52 ERROR: [State] Received unknown message: None
uuid: 1b234d30-92ae-11e3-aa12-7071bcb09717
Thread: 152
01:52 ERROR: [State] Received unknown message: None
uuid: 1b234d30-92ae-11e3-aa12-7071bcb09717
Thread: 32
01:52 INFO: [AddEntity] 1b234d30-92ae-11e3-aa12-7071bcb09717: Cube@2f9c3beb
Thread: 152
这毕竟是线程问题吗?在 Actor 内?
编辑 2
按照下面海报的建议,我记录了 other 和 None 的类名、类加载器引用和类文件路径。它们都是一样的。
编辑 3
other == None 是 false
other.eq(None) 是 false
other.equals(None) 是 false
other.hashCode == None.hashCode
System.identityHashCode(other) != System.identityHashCode(None)
【问题讨论】:
-
您确定您的“其他”案例没有打印相同的信息吗? ☺
-
您是否收到编译器警告,例如无法访问的代码?
-
如果我删除第一个“case other”,有时程序会崩溃,说它无法匹配 scala.None。
-
另外,请提供
world的定义。另一件事要尝试:记录other.getClass.getName和None.getClass.getName。如果他们都是scala.None$,那就太奇怪了。 -
有趣。是否可以提供包含修改地图的逻辑的完整代码?
标签: multithreading scala jvm akka actor