2012-09-06 20 views
0

我使用Akka为Scala演员模型编程,为了充分和充分地使用我的结构的某些功能,我决定使用从Scala抽象类到Akka ActorRef的隐式转换。它是这样的:斯卡拉隐式转换为Akka ActorRef阻止访问Akka的发送操作符“!”,为什么?

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方法。我可以忍受不能使用“!”但我想明白为什么转换会导致这种行为,或者我错过了什么?

谢谢!

回答

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 

}