如何在actor接收内终止处理?

时间:2014-02-16 16:18:09

标签: scala akka actor

我目前在我的akka​​演员的接收方法中有一些巨大的if块。例如:

def receive = {
  case Alarm(msg) => 
    if (msg != null) {
      [... huge amount of code ...]
    } else {
      logger.log("false alarm")
    }
}

由于我认为这不是最好的可读代码,我想知道我是否可以做那样的事情。

def receive = {
  case Alarm(msg) =>
    if (msg == null) {
      logger.log("false alarm")
      break // ????? (I know this does not work, but what else?)
    }
    [... huge amount of code ...]
}

有任何建议或最佳做法吗?

编辑:好的,我知道我必须更精确。我在大量的代码块中有很多数据库查询,并且不希望将 ALL 包装到if else构造中。

Edit2:问题是,我的演员需要做一堆数据库操作,并且需要确保每个数据集都存在才能处理它。由于稳健性要求,我必须这样做。

2 个答案:

答案 0 :(得分:3)

这不是真正的Akka相关问题,因为这里的主要问题是模式匹配并遵守receive的返回类型。 receive是具有此返回类型的部分函数:PartialFunction[Any, Unit]。因此,您不必返回if/else语句中的任何特定内容。因此,你可以log而不需要任何break

要改进样式,您可以使用以下方法之一来编写模式匹配表达式:

scala> case class Alarm(msg: String)
defined class Alarm

scala> Alarm(null) match {
     |   case Alarm(null) => "Null"
     |   case Alarm(_) => "NOT null"
     | }
res1: String = Null

scala> Alarm(null) match {
     |   case Alarm(smth) if(smth == null) => "Null"
     |   case Alarm(_) => "NOT null"
     | }
res2: String = Null

在这种情况下,第一个选项更简洁,更好。

offtopic :避免使用null,而是使用Option[T]case object

附加(使用案例对象):

scala> sealed trait AlarmLike
defined trait AlarmLike

scala> case class Alarm(msg: String) extends AlarmLike
defined class Alarm

scala> case object EmptyAlarm extends AlarmLike
defined module EmptyAlarm

scala> val l: List[AlarmLike] = List(Alarm("Ahtung!"), EmptyAlarm)
l: List[AlarmLike] = List(Alarm(Ahtung!), EmptyAlarm)

scala> l map { case Alarm(desc) => desc; case EmptyAlarm => "EmptyAlarm" }
res0: List[String] = List(Ahtung!, EmptyAlarm)

答案 1 :(得分:1)

要么你已经拥有if-else,要么把它分成不同的情况:

def receive = {
  case Alarm(msg) => 
    if (msg != null) {
      [... huge amount of code ...]
    } else {
      logger.log("false alarm")
    }
}

变为

def receive = {
  csae Alarm(null) => logger.log("false alarm")
  case Alarm(msg) => [... huge amount of code ...]
}