문제

I am currently having some huge if blocks within the receive methods of my akka actors. Example:

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

Since I think this is not the best readable code, I was wondering if I can do something like that.

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 ...]
}

Any suggestions or best practices?

Edit: Okay I see I have to be more precise. I am having a lot of database queries within the huge amount of code block and dont want to wrap ALL those into an if else construct.

Edit2: The thing is, that my actor needs to do a bunch of database operations and that it needs to ensure that each dataset is present before it can process it. I have to do this due to robustness requirements.

도움이 되었습니까?

해결책 2

Either have if-elses like you already have, or divide it up into different cases:

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

becomes

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

다른 팁

This is not really Akka related question because the main problem here is pattern matching and complying with return type of receive. receive is a partial function that has this return type: PartialFunction[Any, Unit]. So you don't really have to return anything specific from your if/else statement. Thus you just can log without any sort of break.

To improve style you can use one of these ways to write the pattern matching expression:

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

The first option is less verbose and better in this case.

offtopic: avoid using null, use Option[T] instead or case object.

Additional (using 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)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top