有时会发生如此神奇的事情,我会弄清楚编译器的作用.例如在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
什么东西吗?
编译器将自动isDefinedAt
从主体生成并且apply
是主体本身.在期望部分函数的情况下,您可以只编写一个由case表达式组成的块,编译器会将其转换为部分函数.
scala> val f: PartialFunction[Any, Any] = { | case x: String => 3 | } f: PartialFunction[Any,Any] =scala> f.isDefinedAt("foo") res1: Boolean = true scala> f.isDefinedAt(23) res2: Boolean = false
编辑:
在底层的akka代码中,将调用receive来设置处理程序函数一次,然后对于每个到达的消息,它尝试应用receive方法并以其他方式调用unhandled
(请参阅链接).
因此只有在处理消息时才会调用处理程序,否则消息将被放入deadletters邮箱中.
编辑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