2
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 //...?

私が本当に欲しいのは、ある種の の自動結合ですB.act() and C.act()が、特性ミックスインでは、 のみB.act()が呼び出されます。これを達成する簡単な方法はありますか?

編集:これが私が見つけた半分の解決策です。Actor元の特性が拡張されなくなり、C with A with B動的な混合ではなくクラスとして定義する必要があるため、「半分」と言います。多分私はそれを「クォーターソリューション」と呼ぶべきですか?

4

2 に答える 2

1

Aおそらく、メッセージを他のアクターのリストに転送するトレイトを作成して、変更したり、変更したりする必要がないようにすることができますB

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 } }
    }
  }
}

もちろんacts、これをインスタンス化するときに、abstract のままにするか、別のセットで上書きすることができます。

于 2012-04-23T00:52:32.330 に答える
1

Actor クラスの拡張:

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])
}

サンプル使用法:

val provider = new Node with Provider
val consumer = new Node with Consumer
val provider_and_consumer = new Node with Provider with Consumer
于 2012-05-30T22:59:08.420 に答える