我在Akka actor实现中有以下接收方法的实现。
override def receive: Receive = {
case SetRequest(key, value) =>{
log.info("Received SetRequest - key:{} ,value:{}", key,value)
map.put(key,value)
sender() ! Status.Success
}
case GetRequest(key) => {
log.info("Received GetRequest for - key:{}", key)
val response: Option[Object] = map.get(key)
response match {
case Some(x) => sender() ! x
case None => sender() ! Status.Failure(new KeyNotFoundException(key))
}
}
case o => Status.Failure(new ClassNotFoundException())
}
我这里的查询很少。
在Actor.scala中,receive定义为:
def receive: Actor.Receive
Actor.Receive是:
type Receive = scala.PartialFunction[scala.Any, scala.Unit]
那么我的接收代码如何符合Actor.Receive?
第二,这种模式匹配的样式是什么?接收似乎没有接受任何参数,所以我实际上想要匹配什么?例如,在代码中我匹配响应,这是有意义的,因为响应是在模式之前计算的匹配。
答案 0 :(得分:2)
那么我的接收代码如何符合Actor.Receive? ... 什么是 这种模式匹配的风格?
在Scala中,str = str.encode('latin-1').decode('utf-8')
是一种常见的部分功能。例如:
case
因此val oneOrTwo: PartialFunction[Int, String] = {
case 1 => "one"
case 2 => "two"
}
// oneOrTwo: PartialFunction[Int,String] = <function1>
val reciprocal: PartialFunction[Double, Double] = { case i if i != 0 => 1 / i }
// reciprocal: PartialFunction[Double,Double] = <function1>
部分函数可用于实现具有case
签名的receive
。
PartialFunction[Any, Unit]
参数类型允许您使用Any
来检查您希望的任何类型的case
(例如,样本中的input
,SetRequest(key, value)
码)。
在返回类型上,GetRequest(key)
允许您在示例代码中输入任何消息处理代码(例如Unit
,sender() ! Status.Success
)并且不要求返回值。
response match {...}
似乎没有得到任何争论,所以我实际上在尝试什么 匹配?
您的类扩展了receive
,因此在覆盖Actor
时,您需要实现在特征receive
中声明的方法(参见下文,来自Akka source code)使用Actor
部分功能。
case
通过扩展object Actor {
type Receive = PartialFunction[Any, Unit]
// ...
}
trait Actor {
def receive: Actor.Receive
// ...
}
并实施方法Actor
,Akka为您的班级配备了所有消息驱动的演员功能,包括mailbox,并指定一个调度程序来提供发送给它的任何消息(例如来自另一个演员的receive
作为myActor ! GetRequest(key)
方法的input
。
答案 1 :(得分:0)
部分函数来自数学,与总函数相对。为所有输入定义了一个总函数,如下所示:
val f = (i: Int) => i + 10
函数f为Int类型的任何输入生成有效结果。 但是这个部分功能:
val g = (i: Int) => 10/i
不会(零会导致错误)。
在Scala中,您可以创建以下特殊函数:
val h: PartialFunction[Int, Int] = {
case i: Int if i != 0 => 10/i
}
它有一个方法isDefinedAt
,可用于检查它是否为给定输入产生有效结果:
h.isDefinedAt(0) // false
h.isDefinedAt(5) // true
您可以像普通函数一样调用部分函数:
h(5)
但是它们也允许你像常规函数一样链接和组合它们orElse
。例如:
val x: PartialFunction[Int, String] = {
case i: Int if i = 10 => "ten"
}
val y: PartialFunction[Int, String] = {
case i: Int if i = 5 => five"
}
val z = y orElse x
z(10) // "ten"
z(5) // "five"
z(0) // MatchError
他们每人只能处理一个案件,他们可以处理两个案件。
对于您的第二个问题: receive
是Actor特征中未实现的方法。它将在您的消息中在Akka实现中的某处调用。它返回一个部分函数,因此可以与PoisonPill
等默认的Akka消息结合使用。