scala - 如何与 Akka Actor 一起使用可堆叠特征模式?

标签 scala akka traits

我正在尝试实现一个 Pub/Sub 特征,以使用可堆叠特征混合到其他 akka actor 中。

这是我的想法:

trait PubSubActor extends Actor {
  abstract override def receive = 
    super.receive orElse {
      case Subscribe(topic) => /* ... */
      case Publish(topic, msg) => /* ... */
    }
}

class MyActor extends Actor with PubSubActor {
  override def receive = {
    case SomeMessage(a, b, c) => /* ... */
  }
}

此时,编译器会抛出一个错误: 错误:在特征 MyActor 中重写方法接收...方法接收需要“抽象重写”修饰符。

你能向我解释一下为什么这不起作用吗?我该如何修复它才能正常工作?

谢谢!

更新

以下作品:

trait PubSubActor extends Actor {
  abstract override def receive = 
    super.receive orElse {
      case Subscribe(topic) => /* ... */
      case Publish(topic, msg) => /* ... */
    }
}

class MyActor extends Actor {
  override def receive = {
    case SomeMessage(a, b, c) => /* ... */
  }
}

class MyActorImpl extends MyActor with PubSubActor

但是为什么呢?为什么我可以通过这种方式获得我想要的行为,而不能通过其他方式获得?有什么理由吗?我似乎无法弄清楚这两个样本之间造成差异的根本区别。

最佳答案

有一个简单而简洁的解决方案:

使用 orElse 定义链接多个接收函数的接收特征:

trait Receiving { 
  var receivers: Receive = Actor.emptyBehavior 
  def receiver(next: Actor.Receive) { receivers = receivers orElse next }
  def receive = receivers // Actor.receive definition
}

在 Actor 中使用它很容易:

trait PubSubActor extends Receiving {
  receiver {
    case Publish => /* I'm the first to handle messages */
  }
}

class MyActor extends PubSubActor with Receiving {
  receiver {
    case SomeMessage => /* PubSubActor didn't handle, I receive the message */ 
  }
}

第一个 PubSubActor 的接收将被调用。如果消息未被处理,它将被传递到 MyActor 的接收。

关于scala - 如何与 Akka Actor 一起使用可堆叠特征模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18124643/

相关文章:

rust - 在 Rust 中为什么需要类型注释,即使它们在通用特征中明确指定

rust - 如何使用serde-json库为包含原始值的结构计算哈希

java - 在Akka模型中共享Cassandra集群/ session

java - System.exit 在 "sbt run"中工作,但在 .jar 中不起作用

scala - akka:如何测试 Actor 是否被停止

Scala 宏 - 使用 `c.prefix` 推断隐式值

PHP - 作为助手的特征

Scala:使用类型参数或抽象类型作为类型边界

java - 如何在java文件中运行scala jar文件?

scala - sbt,publishLocal,解决错误