Frage

Ich bin neu in scala. Als Schauspieler lernen, habe ich versucht, es zu verlängern eine Zeile def zu speichern:

import scala.actors.Actor
import Actor._
class Actoo(actoo: =>Unit) extends Actor {
    def act() {actoo}
}
object run extends Application {
    /* 
    // this one runs well
    val a = new Actor {
        def act() {
            receive { case 1 => println("1") }
        }
    }
    */
    val a = new Actoo {
        receive { case 1 => println("1") }
    }
    a.start
    a ! 1
}

Dann werden die Ausnahme Spur sieht wie folgt aus:

java.lang.AssertionError: assertion failed: receive from channel belonging to other actor
    at scala.Predef$.assert(Predef.scala:92)
    at scala.actors.Actor$class.receive(Actor.scala:424)
    at Actoo.receive(actoo.scala:3)
    at run$$anon$1.<init>(actoo.scala:16)
    at run$.<init>(actoo.scala:15)
    at run$.<clinit>(actoo.scala)
    at run.main(actoo.scala)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at scala.tools.nsc.ObjectRunner$$anonfun$run$1.apply(ObjectRunner.scala:75)
    at scala.tools.nsc.ObjectRunner$.withContextClassLoader(ObjectRunner.scala:49)
    at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:74)
    at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:154)
    at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)

Es kann viele Alternativen, die das gleiche tun kann, aber es ist besser, wenn ich den Grund zu wissen, warum der obige Code funktioniert nicht.

War es hilfreich?

Lösung

Es ist ziemlich einfach. Dieses Verhalten ist nicht aufgrund Akteure Bibliothek, in der Tat. Das Stück Code

val a = new Actoo {
        receive { case 1 => println("1") }
    }

wird von einem Compiler interpretiert als „neue Instanz von Actoo erstellen“ mit einer Initialisierung Körper receive {...} und val actoo wird zu () gleich. So Ihr Code equivivalent zu

val a = new Actoo() {
        receive { case 1 => println("1") }
    }

Um den Code zu beheben, müssen Sie Schreib

val a = new Actoo ({
        receive { case 1 => println("1") }
    })

Andere Tipps

Es gibt auch eine actor Methode in dem Actor Singletons das tut, was Sie wollen. Es gibt sogar ruft start automatisch für Sie.

import scala.actors.Actor
import Actor._

val a = actor {
  receive { case 1 => println("1") }
}

a ! 1

Sie tatsächlich versuchen, aus Postfach auf dem aktuellen nativen Thread zu empfangen (native Threads sind Schauspieler als auch).

Erleben Sie die folgenden Schritte aus:

Welcome to Scala version 2.7.5.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_13).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import scala.actors.Actor._
import scala.actors.Actor._

scala> self ! 123

scala> receive { case x => println(x) }
123

Nun, was wollen Sie ist bereits in der Bibliothek erreichen (Actor.actor):

val a = actor {
  receive { case x => println(x) }
}
// no need to start a 
a ! 123

BTW, ist es eine sehr schlechte Idee Anwendung zu erweitern. Verwenden def main(args: Array[String]) statt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top