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
对我来说唯一可行的解决方案是我在最初的问题中描述的方式。
我正在使用 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
对我来说唯一可行的解决方案是我在最初的问题中描述的方式。