Scala 2.12中Akka Actor转发Fizzbuzz消息失败求助
问题分析与解决思路
这个问题的根源是你误用了Scala中_的含义,导致实际发送的并不是你想要的Fizzbuzz消息。咱们拆解一下问题,再给出修正方案:
为什么原有代码不生效?
你在case Fizzbuzz =>代码块里写的actor1 ! _,这里的_并不是指代当前匹配到的Fizzbuzz实例。在Scala的局部代码块中,_是一个未绑定的匿名参数占位符,编译器会把这种写法解析为发送Unit类型的消息(也就是())——这完全不是你要转发的内容,所以目标Actor自然收不到预期的Fizzbuzz消息。
修正后的代码方案
你需要把匹配到的Fizzbuzz消息绑定到一个变量上,再用这个变量完成转发:
class Foo extends Actor { override def receive: Receive = { case Bar => println("Bar!") case Whitstle => println("Whistle!") case fizzbuzzMsg: Fizzbuzz => val actor1 = context.actorSelection("/user/a1") val actor2 = context.actorSelection("/user/a2") val actor3 = context.actorSelection("/user/a3") actor1 ! fizzbuzzMsg actor2 ! fizzbuzzMsg actor3 ! fizzbuzzMsg } }
更简洁的优化写法
如果这些目标Actor是固定的,建议把actorSelection的初始化移到Actor创建阶段(避免每次接收消息都重复做路径查找),再用批量操作简化代码:
class Foo extends Actor { // 提前初始化目标Actor的选择器,复用资源 private val targetActors = List( context.actorSelection("/user/a1"), context.actorSelection("/user/a2"), context.actorSelection("/user/a3") ) override def receive: Receive = { case Bar => println("Bar!") case Whitstle => println("Whistle!") case msg: Fizzbuzz => targetActors.foreach(_ ! msg) } }
额外的Akka转发建议
如果需要保留原始消息的发送者信息(让目标Actor回复时直接发给最初的消息发送者,而不是当前的Foo Actor),可以用forward代替!:
targetActors.foreach(_ forward msg)
内容的提问来源于stack exchange,提问作者hotmeatballsoup
相关产品推荐
相关产品推荐

