Scala模式匹配始终为默认情况

时间:2016-09-14 08:23:09

标签: scala

首先,我对scala相对较新。

考虑以下简单类NullLogService,它将结果记录到控制台。

package services

import akka.actor._
import com.amazonaws.services.simpleemail.model.SendRawEmailResult
import model.Email

import scala.util.Try

object NullLogService {
  case class Log(email: Email, amazonResult: Try[_])
  case class LogError(email: Email, amazonException: Try[_])
}

class NullLogService  extends Actor {
  import NullLogService._

  def receive = {
    case Log(email, amazonResult) => println("Email to: " + email.to + ". AmazonResultSucess:" + amazonResult.isSuccess.toString + ". AmazonResult: " + amazonResult.get.toString)
    case LogError(email, amazonException) => println("Error: Email to: " + email.to + ". AmazonException:" + amazonException.get.toString)
    case default@_ => println("Default case: "+default.toString)
  }
}

始终打印Default case: Log(TO:email@email.com,Success({MessageId: Fake_Sent_OK}))

我不知道发生了什么,因为类型相同(Log(Email,Try(_)))!它应该转到“Log”情况但总是属于默认情况!

让我发疯。

涉及的代码

主要课程:

import java.io.File
import java.util.concurrent.TimeUnit

import akka.actor.SupervisorStrategy.Resume
import akka.actor._
import akka.routing.RoundRobinPool
import akka.util.Timeout
import com.thenewmotion.akka.rabbitmq._
import com.typesafe.config.{ConfigFactory, ConfigParseOptions}
import model.Email
import services.EmailService.EmailInfo
import services.{EmailService, LogService, NullLogService}
import utils.StringUtils

import scala.concurrent.duration.Duration

object Main extends App {
  implicit val system = ActorSystem()

  val emailServiceRef: ActorRef = system.actorOf(RoundRobinPool(rate).withSupervisorStrategy(supervisorStrategy).props(Props(new EmailService)), "emailWorkerPool")
  val logServiceRef = system.actorOf(RoundRobinPool(1).props(Props(new NullLogService)), "logWorker")
  val email = new Email(stringMap.apply("USEREMAIL"), stringMap.apply("REPLYTO"), stringMap.apply("SUBJECT"), stringMap.apply("BODY"), unsubscribeURL)
  emailServiceRef ! EmailInfo(email, logServiceRef)
}

EmailService:

package services

import akka.actor._
import com.amazonaws.services.simpleemail.model.SendRawEmailResult
import model.Email
import services.LogService.{Log, LogError}

object EmailService {
  case class EmailInfo(email: Email, logServiceRef: ActorRef)
}

class EmailService extends Actor {
  import EmailService._

  def receive = {
    case EmailInfo(email, logServiceRef) =>    
      val emailResult = new SendRawEmailResult
      emailResult.setMessageId("Fake_Sent_OK" )
      val amazonResult = Try( emailResult )
      logServiceRef ! Log(email, amazonResult)
 }
}

2 个答案:

答案 0 :(得分:1)

据推测,您尚未删除LogService.LogLogService.LogError,否则您的EmailService会出现编译错误。在这种情况下,NullLogService不应定义自己的消息,而是使用LogService的消息:

package services

import akka.actor._
import com.amazonaws.services.simpleemail.model.SendRawEmailResult
import model.Email

import scala.util.Try
import LogService.{Log, LogError}

// no object NullLogService unless you need it for something else

class NullLogService extends Actor {
  def receive = {
    case Log(email, amazonResult) => println("Email to: " + email.to + ". AmazonResultSucess:" + amazonResult.isSuccess.toString + ". AmazonResult: " + amazonResult.get.toString)
    case LogError(email, amazonException) => println("Error: Email to: " + email.to + ". AmazonException:" + amazonException.get.toString)
    case default@_ => println("Default case: "+default.toString)
  }
}

然后,您可以在不使用每次更改导入的情况下在使用相同协议(例如NullLogServiceSlf4jLogServiceInMemoryLogService)的不同服务之间切换。

答案 1 :(得分:0)

发现错误。我不得不改变我导入的记录器类 我现在使用NullLogService,而不是LogService。

package services

import akka.actor._
import com.amazonaws.services.simpleemail.model.SendRawEmailResult
import model.Email
//Change this --> import services.LogService.{Log, LogError} <---
//To the class you are using --v
import services.NullLogService.{Log, LogError}


object EmailService {
  case class EmailInfo(email: Email, logServiceRef: ActorRef)
}

class EmailService extends Actor {
  import EmailService._

  def receive = {
    case EmailInfo(email, logServiceRef) =>    
      val emailResult = new SendRawEmailResult
      emailResult.setMessageId("Fake_Sent_OK" )
      val amazonResult = Try( emailResult )
      logServiceRef ! Log(email, amazonResult)
 }
}

这很奇怪,因为没有运行时错误(例如&#34; NullLogService未导入&#34;)