[英]scala syntax understanding about loop and receive in actor
I noticed it is legal to write this scala
code: 我注意到编写此
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.")
}
}
}
I know from documentation that actor
is a trait, which has loop
and receive
value members. 我从文档中知道
actor
是一个特征,它具有loop
并receive
值成员。 But how is it possible to stack these methods like above? 但是如何像上面那样堆叠这些方法呢? Is it implementing or overriding these methods?
它是实现还是覆盖了这些方法? I am quite confused at this syntax.
我对这种语法很困惑。 Please provide some good references/pointers.
请提供一些良好的参考/指针。
First, a standard disclaimer. 首先,是标准的免责声明。 Scala Actors have been deprecated in favor of Akka Actors.
不推荐使用Scala演员,而推荐使用Akka演员。 If you want to continue down the path of learning to use Actors with Scala, you should look into Akka instead of researching Scala Actors.
如果您想继续学习将Actor与Scala结合使用的方法,则应该研究Akka而不是研究Scala Actors。
Now, about your question. 现在,关于您的问题。 There are a couple of things in play here, so let's first start out with what you need to do in order to define a new Scala Actor.
这里有很多事情在做,所以让我们首先从定义新的Scala Actor所需要做的事情开始。 If you look at the Scala Actor trait, you see that there is one abstract method that you must provide called
act():Unit
. 如果查看Scala Actor特性,您会发现必须提供一种抽象方法,称为
act():Unit
。 This is a method that takes no inputs and returns no inputs. 此方法不接受任何输入,也不返回任何输入。 It defines the actors behavior.
它定义了演员的行为。 So in it's simplest form, a custom Scala Actor could be:
因此,以最简单的形式,自定义Scala Actor可以是:
class MyActor extends Actor{
def act(){
}
}
Now this not a very interesting actor as it does nothing. 现在,这不是一个非常有趣的演员,因为它什么也不做。 Now, one way to provide behavior is to invoke the
receive
method, providing a PartialFunction[Any,R]
where R is a generic return type. 现在,提供行为的一种方法是调用
receive
方法,提供PartialFunction[Any,R]
,其中R是通用返回类型。 You could do that like so: 您可以这样做:
class MyActor extends Actor{
def act(){
receive{
case "foo" => println("bar")
}
}
}
So now if this actor receives a message "foo", it will print "bar". 因此,现在,如果此参与者收到消息“ foo”,它将打印“ bar”。 The problem here is that this will only happen for the first message and then won't do anything after.
这里的问题是,这只会在第一个消息发生,然后在之后将不做任何事情。 To fix that.
要解决这个问题。 we can wrap our call to
receive
with a call to loop
to make it continue to do the provided receive
call for each received message: 我们可以将我们的调用包装为具有
loop
调用的receive
,以使其继续为receive
的每条消息执行提供的receive
调用:
class MyActor extends Actor{
def act(){
loop{
receive{
case "foo" => println("bar")
}
}
}
}
So this is now starting to look like your example a bit more. 因此,现在开始看起来像您的示例。 We are leveraging the
loop
and receive
methods that come with the Actor
trait in order to give this actor behavior. 我们利用
loop
并receive
Actor
特性附带的方法来赋予此actor行为。 Lastly, instead of defining an explicit class as my actor, I can define one on the fly with the actor
method on the Actor
companion object. 最后,我可以使用
Actor
随播对象上的actor
方法动态定义一个类,而不是将其定义为我的actor。 That method takes a function body that will be used as the act
impl like this: 该方法采用一个函数体,该函数体将用作如下所示的
act
:
def actor(body: => Unit){
val a = new Actor {
def act() = body
override final val scheduler: IScheduler = parentScheduler
}
}
So in your example, you are creating a new actor implementation on the fly and providing an impl for act
that will loop and call receive
continually with the partial function you supplied for message handling. 因此,在您的示例中,您正在动态创建一个新的actor实现,并为该
act
提供了一个impl,它将使用您提供的用于消息处理的部分函数连续循环和调用receive
。
Hopefully this clarifies things a bit. 希望这可以澄清一些事情。 The only method you are "overriding" (providing an impl for) is
act
. 您要“覆盖”(为其提供隐含)的唯一方法是
act
。 When you see loop
and receive
, those are not overrides; 当您看到
loop
和receive
,这些不是覆盖。 they are simply calls to those existing methods on the Actor
trait. 它们只是调用
Actor
特性上的现有方法。
Actually it's illegal without import Actor._
. 实际上,如果没有
import Actor._
这是非法的。
Your code without that import: 您没有导入的代码:
val fussyActor = Actor.actor {
Actor.loop {
Actor.receive { ... }
}
}
actor
, loop
and receive
are methods of object Actor
. actor
, loop
和receive
是对象Actor
方法。
def actor(body: ⇒ Unit): Actor
def loop(body: ⇒ Unit): Unit
def receive[A](f: PartialFunction[Any, A]): A
Method actor
accepts by-name
Untit
parameter body
- some code block to execute in separate thread and creates an Actor
with act
method implemented using parameter body
. 方法
actor
接受by-name
Untit
参数body
-一些代码块以在单独的线程中执行,并创建具有使用参数body
实现的act
方法的Actor
。
Method loop
accepts by-name
Untit
parameter body
- some code block to execute in infinite loop. 方法
loop
接受by-name
Untit
参数body
-一些代码块在无限循环中执行。
Method receive
accepts PartialFunction
as parameter f
and calls f
with message as parameter. 方法
receive
接受PartialFunction
作为参数f
并以消息作为参数调用f
。 It takes message from actor associated with current thread. 它从与当前线程关联的actor获取消息。
Note that scala actors are deprecated, you should use akka actors. 请注意,scala actor已过时,您应该使用akka actor。 See The Scala Actors Migration Guide .
请参阅《 Scala Actor迁移指南》 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.