[英]How to implement receive () in Akka Actor
I am in the process of converting Akka UntypedActors in Java code to their Scala equivalent. 我正在将Java代码中的Akka UntypedActors转换为他们的Scala等价物。
However, I am having trouble understanding how to correctly implement the receive() abstract method. 但是,我无法理解如何正确实现receive()抽象方法。 The ScalaDoc is a little confusing and most of the examples I see just involve String messages!
ScalaDoc有点令人困惑,我看到的大部分示例都涉及String消息!
My Actor can support multiple message types and this is my solution so far: 我的Actor可以支持多种消息类型,这是我目前的解决方案:
override def receive = {
case message if message.isInstanceOf[ClassOne] => {
// do something after message.asInstanceOf[ClassOne]
}
case message if message.isInstanceOf[ClassTwo] => {
// do something after message.asInstanceOf[ClassTwo]
}
case message => unhandled(message)
}
Is there a better way to achieve the above? 有没有更好的方法来实现上述目标?
override def receive = {
case c: ClassOne =>
// do something after message.asInstanceOf[ClassOne]
case c: ClassTwo =>
// do something after message.asInstanceOf[ClassTwo]
case message => unhandled(message)
}
If you're using case classes, you can get more sophisticated. 如果你正在使用案例类,你可以变得更复杂。
case class ClassOne(x: Int, y: String)
case class ClassTwo(a: Int, b: Option[ClassOne])
override def receive = {
case ClassOne(x, y) =>
println(s"Received $x and $y")
case ClassTwo(a, Some(ClassOne(x, y)) if a == 42 =>
// do something
case ClassTwo(a, None) =>
case c @ ClassOne(_, "foo") => // only match if y == "foo", now c is your instance of ClassOne
}
All sorts of fun stuff. 各种有趣的东西。
receive
's type is really just a PartialFunction[Any,Unit]
, which means you can use Scala's pattern match expressions - in fact, you're already doing it, just not entirely succinctly . receive
的类型实际上只是一个PartialFunction[Any,Unit]
, 这意味着你可以使用Scala的模式匹配表达式 - 事实上,你已经在做了,只是不完全简洁 。 A terser equivalent that would also let you handle the type of the match for each case: 一个等同的terser,它也可以让你处理每个案例的匹配类型:
def receive = {
case classOneMessage : ClassOne => {
// do something
}
case classTwoMessage : ClassTwo => {
// do something
}
case _ => someCustomLogicHereOtherWiseThereWillBeASilentFailure
//you can, but you don't really need to define this case - in Akka
//the standard way to go if you want to process unknown messages
//within *this* actor, is to override the Actor#unhandled(Any)
//method instead
}
Read the tour article , and the already-linked tutorial for more info on pattern matching, especially in the context of using the feature together with case classes - this pattern is applied regularly when working with Akka, for example here in the Akka manual when handling the ActorIdentity
case class . 阅读旅游文章和已经链接的教程 ,了解有关模式匹配的更多信息,特别是在将该功能与案例类一起使用的背景下 - 这种模式在使用Akka时会定期应用,例如在处理Akka手册时
ActorIdentity
案例类 。
receive
is a regular partial function in Scala. receive
是Scala中的常规部分函数。 You can write something like this in your case: 你可以在你的情况下写这样的东西:
case class Example(number: Int, text: String)
override def receive = {
case message: ClassOne =>
// do something with ClassOne instance
case message: ClassTwo =>
// do something with ClassTwo instance
case Example(n, t) =>
println(t * n)
case Example(n, t) if n > 10 =>
println("special case")
}
You don't have to include a special case for unhandled messages unless your application logic requires you to handle all possible messages. 除非您的应用程序逻辑要求您处理所有可能的消息,否则您不必为未处理的消息包含特殊情况。
First two cases just match by type of a message and subtypes will be matched as well. 前两种情况只是按消息类型匹配,子类型也将匹配。 Last one not only matches the type
Example
but also "deconstructs" it using pattern matching. 最后一个不仅匹配类型
Example
而且还使用模式匹配“解构”它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.