阿卡。有没有办法在两个接收之间共享代码?

时间:2016-07-08 09:11:18

标签: scala akka

假设我有几个接收并使用了()unbecome()来切换它们。所有收到的都有一些常见的消息处理。像这样:

class Test extends Actor {

  override def receive: Receive = first

  def first: Receive = {
    case "common" => // how to share?
      println("common stuff")
    case "second" =>
      println("move to second")
      context.become(second)
  }

  def second: Receive = {
    case "common" =>  // how to share?
      println("common stuff")
    case "first" =>
      println("move to first")
      context.become(first)
  }

}

现在我看到两种方式:

  • “common”和“common”上的重复模式匹配 在handleCommon()
  • 之类的函数中处理它
  • 合并收到喜欢 这个,但对我来说似乎不对。

以下是第二个例子:

class Test extends Actor {

      override def receive: Receive = merge(common, first)

      def common: Receive = {
        case "common" =>
          println("common stuff")
      }

      def first: Receive = {
        case "second" =>
          println("move to second")
          context.become(merge(common, second))
      }

      def second: Receive = {
        case "first" =>
          println("move to first")
          context.become(merge(common, first))
      }

      private def merge(functions: Receive*): Receive = {
        case any =>
          val fOpt = functions find (_.isDefinedAt(any))
          if (fOpt.isDefined) {
            fOpt foreach (f => f(any))
          } else {
            unhandled(any)
          }
      }
    }

我确信必须有更好的方法来做到这一点。有吗?

1 个答案:

答案 0 :(得分:2)

您可以使用orElse

def common: Receive = {
  case "common" =>
    println("common stuff")
}

def first: Receive = ({
  case "second" =>
    println("move to second")
    context.become(second)
}: Receive) orElse common

def second: Receive = ({
  case "first" =>
    println("move to first")
    context.become(first)
}: Receive) orElse common

请注意,您必须在表达式的末尾显式注释类型,否则scala将推断Function1而不是Receive