【发布时间】:2020-11-23 16:55:58
【问题描述】:
此代码来自 akka 文档。它使用推荐的函数式风格来影响演员:
import akka.actor.typed.Behavior
import akka.actor.typed.scaladsl.ActorContext
import akka.actor.typed.scaladsl.Behaviors
object Counter {
sealed trait Command
case object Increment extends Command
final case class GetValue(replyTo: ActorRef[Value]) extends Command
final case class Value(n: Int)
def apply(): Behavior[Command] =
counter(0)
private def counter(n: Int): Behavior[Command] =
Behaviors.receive { (context, message) =>
message match {
case Increment =>
val newValue = n + 1
context.log.debug("Incremented counter to [{}]", newValue)
counter(newValue)
case GetValue(replyTo) =>
replyTo ! Value(n)
Behaviors.same
}
}
}
actor 包含一个递归调用“counter(newValue)”以通过函数方式维护可变状态。当我实现它并将@tailrec 注释添加到函数时,scala 编译器会抱怨调用不是尾递归,即使它似乎在最后一个位置。这意味着,迟早会发生堆栈溢出异常(假设您只想计算所有传入的消息并且有数十亿条消息 - 没有足够大的 Java 堆栈)。
是否可以使调用尾递归,或者我必须回退到具有可变变量的面向对象样式来处理这些情况?
【问题讨论】:
-
它不是尾递归,因为函数所做的最后一件事是创建行为。别担心。这是使用 Akka Typed 的推荐方式。
-
这能回答你的问题吗? Akka context become recursive function
标签: scala recursion akka akka-typed