Typed Actor中如何实现经典Actor的become和unbecome行为切换
问题根因
你代码的核心错误是误用了Behaviors.same标记:
Behaviors.same是Akka Typed的特殊返回标记,仅在消息处理函数返回时由框架解析,含义是「保持当前正在运行的行为不变」,它本身不是具体的行为实例。- 你在
answerMachine处理Behave消息时,给EchoMachine传入的第二个参数是Behaviors.same,此时框架不会把这个标记替换为answerMachine本身。 - 当
EchoMachine处理Back消息返回你传入的Behaviors.same时,框架解析到这个标记,会保持当前运行的EchoMachine行为不变,所以不会切回answerMachine。
修复方案
如果你的需求是切到EchoMachine后返回固定的主行为answerMachine,直接把传给EchoMachine的第二个参数改为answerMachine本身即可:
def answerMachine: Behavior[Message] = Behaviors.setup { context: ActorContext[Message] => Behaviors.receiveMessage { case s@Behave => println("Am told to behave: changing like chameleon") // 把要返回的主行为answerMachine直接传给EchoMachine EchoMachine(s, answerMachine) case Back() => println("Now am back") Behaviors.same } } // firstMsg参数你没有使用,可以按需保留或删除 def EchoMachine(firstMsg: Message, behav: Behavior[Message]): Behavior[Message] = Behaviors.setup { context: ActorContext[Message] => Behaviors.receiveMessage { case Back() => println("I have changed to EchoMachine..") // 直接返回传入的目标行为即可完成切换 behav case Behave => println("I am behaving oo") behav } } val system = ActorSystem(TypedConvo.answerMachine, "Machine") system.ref ! Behave system.ref ! Back()
多行为多级返回扩展
如果你要实现3个行为的切换+返回上一级(不是固定返回主行为),只需要每次切换行为时,把当前行为实例作为「返回栈」参数传给下一个行为即可:
- 主行为A切到行为B时,传A实例给B
- 行为B切到行为C时,传B实例给C
- C收到Back返回B实例,B收到Back返回A实例,即可实现逐级返回
内容的提问来源于stack exchange,提问作者Adebari Olalekan
相关产品推荐
相关产品推荐

