scala语法理解循环和接收actor

Qia*_* Li 1 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.")
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我知道,从文档即actor是一个特点,它具有loopreceive值的成员.但是如何像上面那样堆叠这些方法呢?它是在实施还是重写这些方法?我对这种语法很困惑.请提供一些很好的参考/指针.

cmb*_*ter 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(){

  }
}
Run Code Online (Sandbox Code Playgroud)

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

class MyActor extends Actor{
  def act(){
    receive{
      case "foo" => println("bar")
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

所以现在如果这个演员收到消息"foo",它将打印"bar".这里的问题是,这只会发生在第一条消息上,然后才会发生.解决这个问题.我们可以换,我们呼吁receive与号召loop,使其继续做所提供的receive号召每个收到的消息:

class MyActor extends Actor{
  def act(){
    loop{
      receive{
        case "foo" => println("bar")
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

所以现在开始看起来更像你的例子了.我们正在利用特征附带的loopreceive方法来Actor为这个角色提供行为.最后,我可以使用随播对象actor上的方法动态定义一个显式类,而不是将显式类定义为我的actor Actor.该方法采用一个函数体,将用作actimpl,如下所示:

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

因此,在您的示例中,您正在动态创建一个新的actor实现,并为它提供一个impl,actreceive使用您为消息处理提供的partial函数不断调用.

希望这能澄清一些事情.你"覆盖"(提供一个impl)的唯一方法是act.当你看到loop并且receive,那些不是覆盖; 它们只是调用Actor特征上的那些现有方法.