1

我注意到编写此scala代码是合法的:

val fussyActor = actor {
  loop {
    receive {
      case s: String => println("I got a String: " + s)
      case _ => println("I have no idea what I just got.")
    }
  }
}

我从文档中知道这actor是一个特征,它具有loopreceive重视成员。但是怎么可能像上面那样堆叠这些方法呢?它是实现还是覆盖这些方法?我对这种语法很困惑。请提供一些好的参考/指针。

4

2 回答 2

5

首先,标准免责声明。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 附带的loopreceive方法来Actor赋予这个actor行为。最后,我可以使用伴生对象actor上的方法动态定义一个类,而不是定义一个显式类作为我的参与者。Actor该方法采用一个函数体,该函数体将用作actimpl,如下所示:

def actor(body: => Unit){
  val a = new Actor {
    def act() = body
    override final val scheduler: IScheduler = parentScheduler
  }
}

因此,在您的示例中,您正在动态创建一个新的 actor 实现,并为其提供一个 implact将循环并receive使用您为消息处理提供的部分函数不断调用。

希望这能澄清一些事情。您“覆盖”(为其提供 impl)的唯一方法是act. 当您看到loopandreceive时,这些不是覆盖;它们只是对Actor特征上那些现有方法的调用。

于 2013-08-26T16:42:05.230 回答
1

实际上,没有import Actor._.

没有该导入的代码:

val fussyActor = Actor.actor {
  Actor.loop {
    Actor.receive { ... }
  }
}

actor,loopreceive是对象的方法Actor

def actor(body: ⇒ Unit): Actor
def loop(body: ⇒ Unit): Unit
def receive[A](f: PartialFunction[Any, A]): A

方法actor接受by-name Untit参数body——一些代码块在单独的线程中执行,并创建一个使用参数实现的Actorwith方法。actbody

方法loop接受by-name Untit参数body- 在无限循环中执行的一些代码块。

方法receive接受PartialFunction作为参数ff以消息作为参数调用。它从与当前线程关联的参与者那里获取消息。

请注意,不推荐使用 scala 演员,您应该使用 akka 演员。请参阅Scala Actors 迁移指南

于 2013-08-26T16:34:04.897 回答