Akka演员中的接收方法
receive method in Akka actor
我在 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中,接收定义为:
def receive: Actor.Receive
Actor.Receive 是:
type Receive = scala.PartialFunction[scala.Any, scala.Unit]
那么我在receive中的代码如何符合Actor.Receive?
其次,这种模式匹配是什么风格?receive 似乎没有收到任何参数,那么我实际上要匹配什么?例如,在代码中我匹配响应,这是有意义的,因为响应是在它之前计算的模式匹配。
偏函数来自数学,与全函数相对。为所有输入定义了总函数,如下所示:
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 trait中一个未实现的方法。它将在 Akka 实现的某处随您的消息一起被调用。它 returns 是一个部分函数,因此它可以与默认的 Akka 消息结合使用,例如 PoisonPill
等等。
So how does my code in receive conforms to Actor.Receive? ... What is
this style of pattern matching?
在Scala中,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
部分函数可用于实现具有 PartialFunction[Any, Unit]
签名的 receive
。
Any
参数类型允许您使用 case
来检查您希望的任何类型的 input
(例如 SetRequest(key, value)
、GetRequest(key)
你的示例代码)。
在return类型上,Unit
允许您放入任何消息处理代码(例如示例代码中的sender() ! Status.Success
、response match {...}
)并且不需要一个 return 值。
receive
seems to receive no argument, so what am I actually trying
to match?
你的class扩展了Actor
,所以在覆盖receive
时,你需要实现traitActor
中声明的方法(见下文,来自Akka source code) 您已经用 case
部分函数完成了。
object Actor {
type Receive = PartialFunction[Any, Unit]
// ...
}
trait Actor {
def receive: Actor.Receive
// ...
}
通过扩展 Actor
和实现方法 receive
,Akka 为您的 class 配备了所有消息驱动的 actor 功能,包括 mailbox 并指定了一个调度程序来提供信息发送给它的任何消息(例如来自另一个演员的 myActor ! GetRequest(key)
)作为 input
到 receive
方法。
我在 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中,接收定义为:
def receive: Actor.Receive
Actor.Receive 是:
type Receive = scala.PartialFunction[scala.Any, scala.Unit]
那么我在receive中的代码如何符合Actor.Receive?
其次,这种模式匹配是什么风格?receive 似乎没有收到任何参数,那么我实际上要匹配什么?例如,在代码中我匹配响应,这是有意义的,因为响应是在它之前计算的模式匹配。
偏函数来自数学,与全函数相对。为所有输入定义了总函数,如下所示:
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 trait中一个未实现的方法。它将在 Akka 实现的某处随您的消息一起被调用。它 returns 是一个部分函数,因此它可以与默认的 Akka 消息结合使用,例如 PoisonPill
等等。
So how does my code in receive conforms to Actor.Receive? ... What is this style of pattern matching?
在Scala中,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
部分函数可用于实现具有 PartialFunction[Any, Unit]
签名的 receive
。
Any
参数类型允许您使用 case
来检查您希望的任何类型的 input
(例如 SetRequest(key, value)
、GetRequest(key)
你的示例代码)。
在return类型上,Unit
允许您放入任何消息处理代码(例如示例代码中的sender() ! Status.Success
、response match {...}
)并且不需要一个 return 值。
receive
seems to receive no argument, so what am I actually trying to match?
你的class扩展了Actor
,所以在覆盖receive
时,你需要实现traitActor
中声明的方法(见下文,来自Akka source code) 您已经用 case
部分函数完成了。
object Actor {
type Receive = PartialFunction[Any, Unit]
// ...
}
trait Actor {
def receive: Actor.Receive
// ...
}
通过扩展 Actor
和实现方法 receive
,Akka 为您的 class 配备了所有消息驱动的 actor 功能,包括 mailbox 并指定了一个调度程序来提供信息发送给它的任何消息(例如来自另一个演员的 myActor ! GetRequest(key)
)作为 input
到 receive
方法。