我是Scala编程的新手,在理解actor如何工作以及如何正确使用它们方面遇到了一些麻烦。
查看an Akka actor的源代码,揭示了以下内容:
trait Actor {
def receive: Actor.Receive // Actor.Receive = PartialFunction[Any, Unit]
}
我对此的第一印象是,Actor是一个特征,它暴露了一个抽象方法receive
,它不带任何参数,然后返回一个部分函数。第一个问题,这是对API的正确解释吗?
接下来,我查看了如何实现actor的文档。示例如下所示:
class HelloActor extends Actor {
def receive = {
case "hello" => println("hello back at you")
case _ => println("huh?")
}
}
显然这里有一些模式匹配,但我很难理解它是如何工作的。例如,我想说我想直接调用receive方法而不使用send
这样的东西,我该怎么做?
答案 0 :(得分:3)
正如其他人已经回答的那样,你永远不应该直接在Actors上调用方法。但你的问题似乎更多是关于" PartialFunction如何在Scala中工作?",对吧?
在Scala中,PartialFunction[In, Out]
为isDefinedAt
等方法提供了一些编译器生成的代码,因此如果为某个参数定义了部分函数,则可以询问它:
scala> val fun: PartialFunction[Any, String] = {
| case 42 => "yes"
| }
fun: PartialFunction[Any,String] = <function1>
scala> fun.isDefinedAt(12)
res0: Boolean = false
scala> fun.isDefinedAt(42)
res1: Boolean = true
scala> fun(42)
res2: String = yes
scala> fun(12)
scala.MatchError: 12 (of class java.lang.Integer)
```
我们在将消息应用于isDefinedAt
函数之前使用receive
方法,如果它无法处理消息,我们会将其传递给unhandled(msg)
,通常只是将消息记录为死信,这样你就可以发现你的Actor没有处理消息。
答案 1 :(得分:2)
例如,让我们说我想直接调用receive方法而不使用send这样的东西,我该怎么做?
你不会。
直接调用actor的receive
函数而不通过它的ActorRef
打破了actor模型的保证:
(除其他外,请参阅What is an actor?)
当您发送ActorRef
消息时,您不会直接与该演员交谈。隐藏在ActorRef
后面的是任意数量的实现细节 - 您可以向路由器或远程演员或死亡演员(或全部三个!)发送消息。隔离演员在此引用背后的细节允许保证作为演员模型的整个点。