Scala,PartialFunction 的默认代码?

Scala, default code for PartialFunction?

我正在使用 Akka,并且想要 运行 一些代码用于 PartialFunction 的所有情况。对于演员监督,我有这样的东西:

val supervisorStrategy = OneForOneStrategy() {
  case npe: NullPointerException => Stop
  case re: RuntimeException => Restart
}

我发现 运行 某些代码无需在每种情况下都重新编写的唯一方法是:

val pf = new PartialFunction[Throwable, Directive] {
  def apply(throwable: Throwable) = {
    doSomething(throwable)
    throwable match {
      case NullPointerException => Stop
      case RuntimeException => Restart
    }
  }

  def isDefinedAt(throwable: Throwable) = true
}

val supervisorStrategy = OneForOneStrategy()(pf)

我环顾四周并找到了其他答案(例如 this one),但找不到任何替代方法来替代我想出的方法。

应该这样做:

val supervisorStrategy = OneForOneStrategy() { 
 case x =>
  doSomething(x)
  x match {
    case npe: NullPointerException => Stop
    case re: RuntimeException => Restart
  }
}

似乎不​​是 Akka 特有的。您始终可以使用 andThen 组合任意两个函数。具体来说:

package com.example

import akka.actor.OneForOneStrategy
import akka.actor.SupervisorStrategy.{Decider, Restart, Stop}

object Answer extends App {
  val doSomething:PartialFunction[Throwable, Throwable] = { case e =>
    println(s"doing something with $e")
    e
  }

  val decide:Decider = {
    case _:NullPointerException => Stop
    case _:RuntimeException => Restart
  }

  val strategy = OneForOneStrategy()(doSomething andThen decide)

  val errors = Seq(new NullPointerException, new RuntimeException)
  errors map strategy.decider foreach println
}

更一般地说:

package com.example

object Answer extends App {
  val inspect:PartialFunction[Throwable, Throwable] = { case e =>
      println(s"inspecting $e")
      e
  }

  val decide:PartialFunction[Throwable, String] = {
    case npe:NullPointerException => "NPE!"
    case iae:IllegalArgumentException => "Bad arg!"
  }

  val combined = inspect andThen decide

  val errors = Seq(new NullPointerException, new IllegalArgumentException)
  errors map combined foreach println
}

感谢其他答案,但在这种 Akka 特定情况下,我无法让它们工作。例如,这不会编译:

val ft = OneForOneStrategy() { x: Throwable =>
  doSomething(x)
  x match {
    case npe: NullPointerException => Stop
    case re: RuntimeException => Stop
  }
}

Error:(48, 47) type mismatch;
found   : Throwable => akka.actor.SupervisorStrategy.Directive
required: akka.actor.SupervisorStrategy.Decider (which expands to) PartialFunction[Throwable,akka.actor.SupervisorStrategy.Directive]

我正在使用 Akka 2.4.11 和 Scala 2.11.8

对我来说唯一可行的解​​决方案是我在最初的问题中描述的方式。