Die Ausweitung Scala Darsteller
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.
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.