Scala 如何始终在receive()内调用方法,即使没有匹配的

Scala 如何始终在receive()内调用方法,即使没有匹配的,scala,akka,Scala,Akka,我对Akka/Scala的世界相当陌生。我试图找出当一个演员接收到一条消息时,即使没有匹配的消息,让它始终执行的最佳方式是什么。我知道receive是PartialFunction,但我想知道是否有比以下更好的方法: def receive: Receive = { case string: String => { functionIWantToCall() println(string) } case obj: MyClass => { fun

我对Akka/Scala的世界相当陌生。我试图找出当一个演员接收到一条消息时,即使没有匹配的消息,让它始终执行的最佳方式是什么。我知道
receive
PartialFunction
,但我想知道是否有比以下更好的方法:

def receive: Receive = {
  case string: String => { 
    functionIWantToCall()
    println(string)
  }
  case obj: MyClass => {
    functionIWantToCall()
    doSomethingElse()
  }
  case _ => functionIWantToCall()
}

我确信Scala中有更好的方法来实现这一点,而不是在每个案例中调用
functionIWantToCall()
。有人能提出一些建议吗:)?

您可以将接收函数包装为“高阶”接收函数

  def withFunctionToCall(receive: => Receive): Receive = {
    // If underlying Receive is defined for message
    case x if receive.isDefinedAt(x) =>
      functionIWantToCall()
      receive(x)

    // Only if you want to catch all messages
    case _ => functionIWantToCall()
  }

  def receive: Receive = withFunctionToCall {
    case string: String => println(string)
    case obj: MyClass => doSomethingElse()
  }
或者,您可以阅读Akka文档中的管道:

我认为这正是解决这类问题所需要的

  val callBefore: Receive => Receive =
    inner ⇒ {
      case x ⇒ functionIWantToCall; inner(x)
    }

  val myReceive: Receive = {
    case string: String => println(string)
    case obj: MyClass => doSomethingElse()
  }

  def receive: Receive = callBefore(myReceive)

这里有一个简单的例子,与Akka无关。这两个匹配表达式是等效的:

{
  case _: A =>
    foo()
    a()
  case _: B =>
    foo()
    b()
  case _ =>
    foo()
}

{
  case m =>
    foo()
    m match {
      case _: A =>
        a()
      case _: B =>
        b()
      case _ =>
    }
}

您希望只在没有其他案例匹配时调用默认案例,还是希望无论是否存在匹配都始终调用函数?+1要使用接收管道,这是一种非常轻量级的模式,它被认为完全符合您的需要。