在 Akka 中创建演员的首选方式是什么?

What is the preferred way to create actors in Akka?

我正在尝试在 Akka 中创建基本的 Actors,但我发现了两种不同的创建 Actor 的方法。一种方法是扩展 akka.actor.Actor 特征并实现 receive 方法,如下所示

import akka.actor.Actor

class HelloActor extends Actor {
  override def receive: Receive = ???
}

其他方法是使用对象并实现 apply() 方法,如下所示:

final case class GreetedMessage(whom: String, from: ActorRef[GreetMessage])
final case class GreetMessage(whom: String, replyTo: ActorRef[GreetedMessage])

object GreeterActor {
  def apply(): Behavior[GreetMessage] = Behaviors.receive { (context, message) =>
    context.log.info("Hello {}!", message.whom)
    message.replyTo ! GreetedMessage(message.whom, context.self)
    Behaviors.same
  }
}

我想知道哪种是创建演员的首选方式,如果可能的话,还有背后的原因。

我假设扩展 Actor trait 是旧方法,因为 Akka 官方网站上没有提到它。请指教。

应该注意的是,您的两个示例都没有创建演员:那是 ActorSystem 的工作。这些示例定义了参与者。

定义演员的第一种方法是"classic"非类型演员API。

第二种方法是类型演员的两个 API 之一(特别是 "functional" 样式 API)。

Akka 文档说:

For new projects, we recommend using the new [typed] Actor APIs.

经典 API 仍然得到完全支持,并且可能会持续很长时间。

还有一种 OO 风格 API 用于定义类型化 actor:

class GreeterBehavior(context: ActorContext[GreetMessage]) extends AbstractBehavior[GreetMessage](context) {
  override def onMessage(message: GreetMessage): Behavior[GreetMessage] = {
    context.log.info("Hello {}!", message.whom)
    message.replyTo ! GreetedMessage(message.whom, context.self)
    this
  }
}

编辑添加:经典 API 已完全记录,例如Akka docs for Actors.

类型化的 APIs 允许编译器至少验证一些消息传递协议。如果你有一个 ActorRef[Foo],你只能发送 Foo 的消息(包括 Foo 的子类型)给演员。也可以验证参与者的行为是否涵盖它可能接收到的所有消息。