我正在使用Akka进行使用Scala的actor模型编程,为了完全充分地使用我的结构的某些功能,我决定使用从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方法。我可以忍受不能使用“!”但是我想理解为什么转换会导致这种行为,或者我错过了什么?
谢谢!
答案 0 :(得分: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
}