Scala 多重特质混合和参与者的问题
我真正想要的是某种自动组合Scala 多重特质混合和参与者的问题,scala,inheritance,actor,mixins,traits,Scala,Inheritance,Actor,Mixins,Traits,我真正想要的是某种自动组合B.act()和C.act(),但是对于trait mix-ins,只调用B.act()。有没有一个简单的方法来实现这一点 编辑:这是我找到的一本书。我之所以说“一半”,是因为最初的特征不再延伸到演员,而带有A和B的C需要定义为一个类,而不是动态混合。也许我应该称之为“四分之一解决方案”?也许你可以制作一个特性,将信息转发给其他参与者的列表,这样你就不必修改a或B: trait A extends Actor { private val s = Set[Int]()
B.act()和C.act()
,但是对于trait mix-ins,只调用B.act()
。有没有一个简单的方法来实现这一点
编辑:这是我找到的一本书。我之所以说“一半”,是因为最初的特征不再延伸到演员,而带有A和B的C需要定义为一个类,而不是动态混合。也许我应该称之为“四分之一解决方案”?也许你可以制作一个特性,将信息转发给其他参与者的列表,这样你就不必修改
a
或B
:
trait A extends Actor {
private val s = Set[Int]()
override def act() {
loop {
react {
// case code that modifies s
}
}
}
}
trait B extends Actor {
private val t = Set[String]()
override def act() {
loop {
react {
// case code that modifies t
}
}
}
}
val c = new C with A with B //...?
当然,在实例化时,您可以将
acts
抽象化,或者使用不同的集合覆盖它。扩展Actor类:
trait C extends Actor {
private val acts: Seq[Actor] = Seq(new A{}, new B{})
override def act() {
acts foreach (_.start)
loop {
react { case x => acts foreach { _ ! x } }
}
}
}
示例代码:
import actors.Actor
class MixableActor extends Actor {
protected var acts = List[PartialFunction[Any, Unit]]()
final override def act() {
loop {
react {
acts.reduce((a, b) => a orElse b)
}
}
}
final def receive(act: PartialFunction[Any, Unit]) {
acts = act :: acts
}
}
示例用法:
abstract class Node extends MixableActor {
...
}
trait User extends MixableActor {
val files = scala.collection.mutable.Set[Data]()
}
trait Provider extends User {
receive({
case ("provide", file: Data) =>
provide(file)
}: PartialFunction[Any, Unit])
}
trait Consumer extends User {
receive({
case ("consume", file: Data) =>
consume(file)
}: PartialFunction[Any, Unit])
}
这是不可能的,
A
和B
都是特征,无法实例化。我假设您的意思是Seq(新的C带A,新的C带B)
,但是请注意,这会导致C
的两个副本,这可能是额外的内存开销。忽略这一点,这是可以的,直到我们有trait A扩展D
和trait B扩展D
。现在我们有两份D
的参数!如果A
和B
都有修改D
参数的情况,我们将如何同步它们?@jiaweili确定有可能:查看上面的代码newa{}
与newanyref with A
相同。我不明白你关于D的论点;演员不应该共享可变状态哦,我不知道大括号语法A
和B
不会共享可变状态,因为所有A
的消息处理程序和B
的消息处理程序一次只能解析一个消息处理程序。所有D
的变量只能有一个副本。您介绍的代码的问题是,消息处理程序在trait的每个实例上都进行了解析-因此,D
的多个副本。a
和B
都可以接收消息吗?当然可以,为什么不可以?我提出的解决方案处理了这个问题——如果A
和B
都有消息的案例处理程序,那么稍后混合的特征在解析时具有优先权。(实际上,我需要将reduce
改为reduceLeft
)实际上,我想我可能误解了你的问题。虽然A
和B
都可以为消息定义一个案例处理程序,但实际上只有其中一个会执行。但是,您可以控制要解决的问题。
val provider = new Node with Provider
val consumer = new Node with Consumer
val provider_and_consumer = new Node with Provider with Consumer