Scala 如何在akka演员接收的模式匹配中提前返回
尝试在谷歌上搜索这个琐碎问题的变体,但没有得到答案 基本上,我的receive方法中有一个模式匹配。 在某些情况下,我希望尽早从接收处理中中断Scala 如何在akka演员接收的模式匹配中提前返回,scala,syntax,akka,partialfunction,Scala,Syntax,Akka,Partialfunction,尝试在谷歌上搜索这个琐碎问题的变体,但没有得到答案 基本上,我的receive方法中有一个模式匹配。 在某些情况下,我希望尽早从接收处理中中断 override def receive = { case blah => { ... preflight code if (preflight failed) { sender() ! errorMSG "break" or "ret
override def receive = {
case blah => {
... preflight code
if (preflight failed) {
sender() ! errorMSG
"break" or "return" here // get error "method receive has a return statement ; needs result type -
// I tried adding Unit to the receive and return statements
}
... more code
....
if (something happened) {
sender() ! anotherErrorMSG
"break" or "return" here
}
...
}
case foo => {...}
case bar => {...}
} // end receive
这可能不是您问题的确切答案,但在您的情况下,添加参与者将是更好的解决方案。在Akka监督模型中,说服您处理主管参与者上的异常,而不是将错误消息发送回发送方 这种方法为您提供了一个容错模型,并且您可以在您想要的任何行上抛出异常(这解决了您当前的问题),您的主管参与者将通过重新启动、恢复或停止子参与者来处理抛出的异常 请检查请参见并记住,receive返回PartialFunction[任何,单位],然后在receive返回后对其进行评估。简言之,没有办法早点回来 Ömer Erden抛出异常并使用参与者监督的解决方案是可行的(事实上,抛出异常及其所有开销基本上是可靠地提前结束计算的唯一方法),但如果您需要任何状态从消息传递到消息,则需要Akka持久性 如果您不想在chunjef的解决方案中嵌套If elses,可以使用context.been和stash创建一些意大利面条式的代码 但最好的解决方案可能是让可能失败的东西是它们自己的函数,并具有任意一种结果类型。请注意,scala 2.12中的任何一个API都比以前的版本要好一些
import scala.util.{ Either, Left, Right }
type ErrorMsg = ...
type PreflightSuccess = ... // contains anything created in preflight that you need later
type MoreCodeSuccess = ... // contains anything created in preflight or morecode that you need later
def preflight(...): Either[ErrorMsg, PreFlightSuccess] = {
... // preflight
if (preflight failed)
Left(errorMsg)
else
Right(...) // create a PreflightSuccess
}
def moreCode1(pfs: PreFlightSuccess): Either[ErrorMsg, MoreCodeSuccess] = {
... // more code
if (something happened)
Left(anotherErrorMSG)
else
Right(...) // create a MoreCodeSuccess
}
def moreCode2(mcs: MoreCodeSuccess): Either[ErrorMsg, Any] = {
... // more code, presumably never fails
Right(...)
}
override def receive = {
case blah =>
val pf = preflight(...)
val result = pf.map(morecode1).joinRight.map(moreCode2).joinRight // only calls morecode1 if preflight succeeded, and only calls morecode2 if preflight and morecode1 succeeded
result.fold(
{ errorMsg => sender ! errorMsg },
()
)
case foo => ...
case bar => ...
}
这是否比嵌套的if-else更可取是一个品味问题…现在我看到了,您也可以将map(…)替换为flatMap(…)。