模式匹配如何在Akka.Actor接收方法中工作?

时间:2014-10-14 02:27:18

标签: scala akka

我是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这样的东西,我该怎么做?

2 个答案:

答案 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模型的保证:

  1. Actors一次处理一条消息。
  2. 演员的内部状态只能从接收功能中变异。
  3. (除其他外,请参阅What is an actor?

    当您发送ActorRef消息时,您不会直接与该演员交谈。隐藏在ActorRef后面的是任意数量的实现细节 - 您可以向路由器或远程演员或死亡演员(或全部三个!)发送消息。隔离演员在此引用背后的细节允许保证作为演员模型的整个点。