我正在实现一些扩展Actor的抽象类,并提供一些额外的功能1。然而,模式匹配似乎不能在接收语句中工作。如果我从客户端向服务器发送了一个案例对象Connect,并且在服务器中有一个模式匹配,则表单如下:
println("Starting to receive, e.g. " + Connect.getClass.toString)
receive {
case Connect => println("Got a connected message")
case m => println("Got something weird: " + m + " of type " + m.getClass.toString)
}则输出为
Starting to receive, e.g. class ConnectionTest$Connect$
Got something weird: Connect of type class ConnectionTest$Connect$
...传入的消息在模式匹配中不会被识别为Connect对象,即使getClass说它是。更奇怪的是:m具有与Connect相同的hashCode,并使用ObjectOutputStream和writeObject序列化到完全相同的ByteArray,但不等同于它(使用==)。我最好的猜测是classLoader不知何故运行不正确,但我不知所措。
下面是我想要写的更完整的例子:
import scala.actors.{Actor, OutputChannel}
import scala.actors.Actor._
import scala.actors.remote.RemoteActor
import scala.actors.remote.RemoteActor._
import scala.actors.remote.Node
abstract class ConnectionTest(masterNode: Node, port: Int) {
trait Message
case object Connect extends Message
abstract class Master extends Actor {
def act {
RemoteActor.classLoader = getClass.getClassLoader
alive(port)
register('MasterProcess, self)
while (true) {
println("Starting to receive, e.g. " + Connect.getClass.toString)
receive {
case Connect => println("Got a connect message")
case m => println("Got something weird: " + m + " of type " + m.getClass.toString)
}
}
}
}
abstract class Worker extends Actor {
def act {
RemoteActor.classLoader = getClass.getClassLoader
val master = select(masterNode, 'MasterProcess)
link(master)
master ! Connect
}
}
}下面是一个使用示例:
object MyConnectionApp extends optional.Application {
case class MyConTest(hostname: String, port: Int) extends ConnectionTest(Node(hostname, port), port) {
case object MyMaster extends Master
case object MyWorker extends Worker
}
def main(master: Boolean) = {
if (master)
MyConTest("localhost", 2552).MyMaster start
else
MyConTest("localhost", 2552).MyWorker start
}
}当我运行这个程序时,输出如下所示。MyMaster的操作方法中的模式匹配无法识别从MyWorker远程接收的Connect消息。尽管getClass.toString对它们的计算结果是相同的,但它们在某种程度上是不同的。我该如何解决这个问题呢?
1更多细节:我正在为跨大量节点的某种并行计算实现一个框架。在更复杂的情况下,我实际上想用ParallelComputation[Data, Result]替换ConnectionTest,其中Data和Result是类型参数。消息还将包括依赖于这些参数的类,如
case object Computed(x: Data, y: Result) extends Message理想情况下,我想要一个与此设计模式配合良好的解决方案。
发布于 2011-12-26 17:04:32
我还没有测试过,但我认为您不应该将Message特征和实现(包括对象Connect)放在ConnectionTest类中。您可以将它们放在一个伴生对象中。如果将它们放在一个类中,则包含类ConnectionTest的每个实例都有一个不同的对象Connect (更糟糕的是,在序列化上下文中,它有一个对该实例的引用)。
属于不同ConnectionTest实例的对象Connect是不同的,并且彼此不匹配。
https://stackoverflow.com/questions/8633019
复制相似问题