2009-09-04 6 views
2

Ich habe den folgenden Code. Wenn ich den Aufruf von "foo()" im Körper des Schauspielers kommentiere, funktioniert der Code gut. Aber wenn "foo()" aktiviert ist ... friert mein Code ein!Methodenaufruf innerhalb Actor gefriert in Scala

Wer kwows warum?

import scala.actors.Actor._ 

object Main extends Application{ 
    def foo() = { 
     println("I'm on foo") 
    } 

    def testActor() = { 
     val target = self 

     for(i <- 1 to 100){ 
      actor{ 
       foo() 
       target ! i 
      } 
     } 

     var total = 0 
     receive{ 
      case x:Int => total += x 
     } 
     total 
    } 

    println("Result: " + testActor()) 
} 

Antwort

2

"testActor" wird aufgerufen, während die Klasse "Main" initialisiert wird. Der Akteurcode wird in einem anderen Thread (nicht im Hauptthread) ausgeführt und ist blockiert und kann keine Nachricht senden, da er versucht, auf eine Methode in einer Klasse (Main in diesem Fall) zuzugreifen, die im Hauptthread initialisiert wird. "Empfangen" hängt, weil es keine Nachricht empfangen kann.

Verwenden Sie nicht "erweitert Anwendung". Verwenden Sie "def main (args: Array [String])" und ersparen Sie sich eine Menge Ärger.

Siehe http://scala-blogs.org/2008/07/application-trait-considered-harmful.html

2

Die Application Eigenschaft und ihre Verwendung ist hier schuld. Wenn Code innerhalb des Körpers einer Application statt innerhalb einer main-Methode ausgeführt wird, wird dieser Code tatsächlich als Teil des Konstruktors ausgeführt. An dem Punkt, an dem Sie die Methode testActor() aufrufen, hat das Objekt die Initialisierung noch nicht abgeschlossen.

es zu beheben, die println Linie in ein Hauptverfahren bewegen:

def main (args: Array[String]) { 
    println("Result: " + testActor()) 
} 

Da dieses Problem so leicht geschieht, das Application Merkmal betrachtet eine schlechte Nachricht zu sein.

+0

Wie hier erwähnt: http://stackoverflow.com/questions/1332574/common-programming-mistakes-for-scala-developers-to-avoid/1334962#1334962 –