1

有时会发生如此神奇的事情,以至于我不知道编译器做了什么。例如在akka中,receive定义为:

def receive: Receive
type Receive = Actor.Receive

Receive定义为:

type Receive = PartialFunction[Any, Unit]

然后我们声明receive为:

def receive = {
     case "a" => //do something
     case "b" => //do something
     case _ => //default
}

我知道PartialFunction但我没有得到的是它如何将消息应用到receive. 我们不是应该提供applyandisDefinedAt因为receive返回 aPartialFunction吗?

从语法上讲,它如何应用于receive消息?它会做类似的message match receive事情吗?

4

1 回答 1

5

编译器会自动isDefinedAt从主体生成,并且apply是主体本身。在需要偏函数的地方,您可以只编写一个由 case 表达式组成的块,编译器会将其转换为偏函数。

scala> val f: PartialFunction[Any, Any] = {
     | case x: String => 3
     | }
f: PartialFunction[Any,Any] = <function1>

scala> f.isDefinedAt("foo")
res1: Boolean = true

scala> f.isDefinedAt(23)
res2: Boolean = false

编辑

在底层的akka​​代码中,将调用receive来设置处理函数一次,然后对于每条到达的消息,它会尝试应用receive方法,否则会调用unhandled(参见链接)。

因此,只有当它可以处理消息时才会调用处理程序,否则消息将被放入死信邮箱。

编辑2

这些是 akka 代码中的相关部分:

如果已定义,则调用处理程序,否则调用未处理:

https://github.com/akka/akka/blob/master/akka-actor/src/main/scala/akka/actor/ActorCell.scala#L496

未处理:

https://github.com/akka/akka/blob/master/akka-actor/src/main/scala/akka/actor/Actor.scala#L545

于 2013-05-24T11:56:24.393 回答