斯卡拉 akka 打字道:如何从Actor示例中获取ActorRef并发送消息本身?

jhkqcmku  于 2022-11-06  发布在  其他
关注(0)|答案(1)|浏览(171)

我想从Actor示例(case类/从其行为创建的类)向其Actor发送消息。
我通过保存instance获得它,然后在其中保存ActorRef

val (instance, behaviour) = MyActorInstance(Nothing)
val actor = ActorSystem(instance, "SomeName123")
//save it here
instance.setMyActor(actor)

object MyActorInstance {
  def apply(ctx: ActorContext[Commands]): (MyActorInstance,Behavior[Commands]) = {
    val actorInstance = new MyActorInstance(ctx)
    val behaviour: Behavior[Commands] =
      Behaviors.setup { context =>
        {
          Behaviors.receiveMessage { msg =>
            actorInstance.onMessage(msg)
          }
        }
      }
    (actorInstance,behaviour)
  }
}

class MyActorInstance(context: ActorContext[Commands]) extends AbstractBehavior[Commands](context) {

  protected var myActorRef: ActorRef[Commands] = null

  def setMyActor(actorRef: ActorRef[Commands]): Unit = {
    myActorRef = actorRef
  }

  override def onMessage(msg: Commands): Behavior[Commands] = {
    msg match {
      case SendMyself(msg) =>
        myActorRef ! IAmDone(msg)
        Behaviors.same
      case IAmDone(msg) =>
        println(s"Send $msg to myself!")
        Behaviors.same
    }
  }
}

这里我把ActorRef保存到Actor的var myActorRef示例中,然后用这个myActorRef通过SendMyself消息把Actor示例的消息发送给它自己。
但是,正如你所看到的,我使用了变量,这是不好的:要保存ActorRef,需要将MyActorInstance类示例的字段myActorRefnull重写为ActorRef-这只能使用variables。
如果我尝试使用瓦尔并通过重写其示例为new来创建不可变类,然后将其从旧示例交换为新示例,我的Actor actor仍然链接到旧示例,其中myActorRef == null
现在我找到了一种方法:只需要使用var而不是val或不可变类。
但是我想使用瓦尔或者什么都不用。为此我需要从它的示例中获取ActorRef,但是怎么做呢?

2fjabf4q

2fjabf4q1#

没有理由这么复杂的舞蹈,只需使用ctx.self。并且请在询问之前至少阅读最基本的文档,它甚至会节省你的时间。

相关问题