0

私は Scala でのアクター モデル プログラミングに Akka を使用しています。私の構造の一部の機能を完全かつ十分に使用するために、Scala 抽象クラスから Akka ActorRef への暗黙的な変換を使用することにしました。次のようになります。

abstract class A {
   val actor = system.actorOf(Props(new C),"dummy")
   def send(msg: String) = actor ! msg // This compiles fine
}

class C extends akka.actor.Actor {
   def receive = {case msg => println(msg)}
}

implicit def AtoC(a:  A) = a.actor

次に、次のように使用します。

class D extends A

val d = new D

通常、変換は正常に機能するため、次のようにするだけで、D のアクターにメッセージを送信できるはずです。

d ! message // This does not compile

しかし、明らかに許可されていません。tell メソッドを引き続き使用できるため、これは大きな問題ではありません。

d.tell(message)

「!」はまだ使えます。代わりにこの変換を使用して:

implicit def AtoC(a:  A) = a.actor.asInstanceOf[ScalaActorRef]

しかし、これを行うと、ActorRef メソッドを使用できなくなります。「!」が使えなくても生きていける。しかし、変換がそのような動作を引き起こす理由を理解したいのですか、それとも何か不足していますか?

ありがとうございました!

4

1 に答える 1

2

Scala は複数の暗黙的な変換を行わないためです。! ActorRef から ScalaActorRef への暗黙的な変換です (Java API からシンボリック メソッドを非表示にするため):

/**
 * This trait represents the Scala Actor API
 * There are implicit conversions in ../actor/Implicits.scala
 * from ActorRef -> ScalaActorRef and back
 */
trait ScalaActorRef { ref: ActorRef ⇒

  /**
   * Sends a one-way asynchronous message. E.g. fire-and-forget semantics.
   * <p/>
   *
   * If invoked from within an actor then the actor reference is implicitly passed on as the implicit 'sender' argument.
   * <p/>
   *
   * This actor 'sender' reference is then available in the receiving actor in the 'sender' member variable,
   * if invoked from within an Actor. If not then no sender is available.
   * <pre>
   *   actor ! message
   * </pre>
   * <p/>
   */
  def !(message: Any)(implicit sender: ActorRef = null): Unit

}
于 2012-09-06T12:40:43.320 に答える