scala语法理解循环和接收actor

时间:2013-08-26 15:57:55

标签: scala actor

我注意到编写此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个值成员。但是如何像上面那样堆叠这些方法呢?它是在实施还是重写这些方法?我对这种语法很困惑。请提供一些很好的参考/指示。

2 个答案:

答案 0 :(得分:5)

首先,标准免责声明。 Scala Actors已被弃用,赞成Akka Actors。如果你想继续学习使用Scala的Actors,你应该研究Akka而不是研究Scala Actors。

现在,关于你的问题。这里有几件事情,所以让我们首先介绍一下你需要做些什么来定义一个新的Scala Actor。如果查看Scala Actor特征,您会发现有一个必须提供的抽象方法称为act():Unit。这是一种不接受任何输入并且不返回任何输入的方法。它定义了actor的行为。因此,在最简单的形式中,自定义Scala Actor可以是:

class MyActor extends Actor{
  def act(){

  }
}

现在这不是一个非常有趣的演员,因为它什么都不做。现在,提供行为的一种方法是调用receive方法,提供PartialFunction[Any,R],其中R是泛型返回类型。你可以这样做:

class MyActor extends Actor{
  def act(){
    receive{
      case "foo" => println("bar")
    }
  }
}

所以现在如果这个演员收到消息“foo”,它将打印“bar”。这里的问题是,这只会发生在第一条消息上,然后才会发生。解决这个问题。我们可以通过拨打receive来打电话给loop,以便继续为收到的每条消息执行receive次呼叫:

class MyActor extends Actor{
  def act(){
    loop{
      receive{
        case "foo" => println("bar")
      }
    }
  }
}

所以现在开始看起来像你的例子了。我们正在利用loop特征附带的receiveActor方法来为此演员提供行为。最后,我可以使用actor伴随对象上的Actor方法动态定义一个显式类,而不是将显式类定义为我的actor。该方法采用一个函数体,将用作act impl,如下所示:

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

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

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

答案 1 :(得分:1)

实际上没有import Actor._是违法的。

没有导入的代码:

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

actorloopreceive是对象Actor的方法。

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

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

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

方法receive接受PartialFunction作为参数f,并使用message作为参数调用f。它接收来自与当前线程关联的actor的消息。

请注意,不推荐使用scala actor,您应该使用akka actors。请参阅The Scala Actors Migration Guide