首先,标准免责声明。Scala Actors 已被弃用,取而代之的是 Akka Actors。如果您想继续学习在 Scala 中使用 Actors,您应该研究 Akka,而不是研究 Scala Actors。
现在,关于你的问题。这里有几件事在起作用,所以让我们首先从定义一个新的 Scala Actor 需要做的事情开始。如果您查看 Scala Actor 特征,您会发现必须提供一个抽象方法,称为act():Unit
. 这是一种不接受输入也不返回任何输入的方法。它定义了参与者的行为。因此,在最简单的形式中,自定义 Scala Actor 可以是:
class MyActor extends Actor{
def act(){
}
}
现在这不是一个非常有趣的演员,因为它什么都不做。现在,提供行为的一种方法是调用该receive
方法,提供PartialFunction[Any,R]
其中 R 是通用返回类型。你可以这样做:
class MyActor extends Actor{
def act(){
receive{
case "foo" => println("bar")
}
}
}
所以现在如果这个actor收到一条消息“foo”,它将打印“bar”。这里的问题是,这只会发生在第一条消息中,之后不会做任何事情。解决这个问题。我们可以用调用来包装我们receive
的调用,loop
以使其继续receive
为每个收到的消息执行提供的调用:
class MyActor extends Actor{
def act(){
loop{
receive{
case "foo" => println("bar")
}
}
}
}
所以这现在开始看起来更像你的例子了。我们正在利用 trait 附带的loop
和receive
方法来Actor
赋予这个actor行为。最后,我可以使用伴生对象actor
上的方法动态定义一个类,而不是定义一个显式类作为我的参与者。Actor
该方法采用一个函数体,该函数体将用作act
impl,如下所示:
def actor(body: => Unit){
val a = new Actor {
def act() = body
override final val scheduler: IScheduler = parentScheduler
}
}
因此,在您的示例中,您正在动态创建一个新的 actor 实现,并为其提供一个 implact
将循环并receive
使用您为消息处理提供的部分函数不断调用。
希望这能澄清一些事情。您“覆盖”(为其提供 impl)的唯一方法是act
. 当您看到loop
andreceive
时,这些不是覆盖;它们只是对Actor
特征上那些现有方法的调用。