使用Akka接收方法在Scala中编写特征行为 [英] Composing trait behavior in Scala in an Akka receive method

查看:73
本文介绍了使用Akka接收方法在Scala中编写特征行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下两个特征:

trait Poked extends Actor {
  override def receive = {
    case Poke(port, x) => ReceivePoke(port, x)
  }

  def ReceivePoke(port: String, x: Any)
}

trait Peeked extends Actor {
  override def receive = {
    case Peek(port) => ReceivePeek(port)
  }

  def ReceivePeek(port: String)
}

现在考虑,我可以创建一个实现这两个特征的新Actor:

Now consider I can create a new Actor that implements both traits:

val peekedpoked = actorRef(new Actor extends Poked with Peeked)

我如何组成接收处理程序?即,接收器应该类似于以下代码,尽管是自动生成的(即所有特征都应组成):

How do I compose the receive handlers? i.e., the receiver should be something like the following code, though "automatically generated" (i.e., all traits should compose):

def receive = (Poked.receive: Receive) orElse (Peeked.receive: Receive) orElse ...


推荐答案

您可以使用 super [T] 来引用特定超类/特征的成员。

You can use super[T] to reference members of particular super classes/traits.

例如:

trait IntActor extends Actor {
    def receive = {
        case i: Int => println("Int!")
    }
}

trait StringActor extends Actor {
    def receive = {
        case s: String => println("String!")
    }
}

class IntOrString extends Actor with IntActor with StringActor {
    override def receive = super[IntActor].receive orElse super[StringActor].receive
}

val a = actorOf[IntOrString].start
a ! 5 //prints Int!
a ! "Hello" //prints String!

编辑:

作为对Hugo的评论的回应,这是一个解决方案,使您可以组合mixins,而无需手动将它们的接收连接在一起。本质上,它涉及具有可变的 List [Receive] 的基本特征,并且每个混合特征都调用一种方法来将其自己的接收添加到列表中。

In response to Hugo's comment, here's a solution that allows you to compose the mixins without having to manually wire their receives together. Essentially it involves a base trait with a mutable List[Receive], and each mixed-in trait calls a method to add its own receive to the list.

trait ComposableActor extends Actor {
  private var receives: List[Receive] = List()
  protected def registerReceive(receive: Receive) {
    receives = receive :: receives
  }

  def receive = receives reduce {_ orElse _}
}

trait IntActor extends ComposableActor {
  registerReceive {
    case i: Int => println("Int!")
  }
}

trait StringActor extends ComposableActor {
  registerReceive {
    case s: String => println("String!")
  }
}

val a = actorOf(new ComposableActor with IntActor with StringActor).start
a ! 5 //prints Int!
a ! "test" //prints String!

唯一要记住的是,接收顺序不重要,因为您虽然您可以通过使用可变的哈希映射而不是列表来解决该问题,但是将无法轻松预测哪个是链中的第一个。

The only thing to keep in mind is that the order of the receives should not be important, since you won't be able to easily predict which one is first in the chain, though you could solve that by using a mutable hashmap instead of a list.

这篇关于使用Akka接收方法在Scala中编写特征行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆