在Akka演员接收方法

时间:2018-05-20 04:02:42

标签: pattern-matching 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中,receive定义为:

def receive: Actor.Receive

Actor.Receive是:

type Receive = scala.PartialFunction[scala.Any, scala.Unit]

那么我的接收代码如何符合Actor.Receive?

第二,这种模式匹配的样式是什么?接收似乎没有接受任何参数,所以我实际上想要匹配什么?例如,在代码中我匹配响应,这是有意义的,因为响应是在模式之前计算的匹配。

2 个答案:

答案 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(例如,样本中的inputSetRequest(key, value)码)。

在返回类型上,GetRequest(key)允许您在示例代码中输入任何消息处理代码(例如Unitsender() ! 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消息结合使用。