有时会发生如此神奇的事情,我会弄清楚编译器的作用。例如,在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
。我们不是要提供apply
和isDefinedAt
,因为receive
会返回PartialFunction
吗?
从语法上讲,它如何将receive
应用于邮件?它做了message match receive
之类的东西吗?
答案 0 :(得分: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
(参见链接)。
所以只有处理器才能处理消息,否则消息将被放入deadletters邮箱。
<强> EDIT2 强>:
这些是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