Scala Faul Val Frage
-
12-10-2019 - |
Frage
Ich habe ein Szenario, in dem ich einige Objekte, die Notwendigkeit, sich voneinander in Referenzen zu nehmen. Die einzige Art, wie ich dies zu kompilieren, ist die Verwendung erhalten kann faul
class A(b:B)
class B(a:A)
lazy val a:A = new A(b)
lazy val b:B = new B(a)
Ich kann das gleiche tun einige Schauspieler verwenden, und bekommen es auch zu kompilieren
abstract class Message
case class Message1 extends Message
case class Message2 extends Message
class Actor1(otherActor:Actor) extends Actor {
def act() {
loop {
react {
case Message1 =>
println("received message1")
otherActor ! Message2
case _ =>
}
}
}
}
class Actor2(otherActor:Actor) extends Actor {
def act() {
loop {
react {
case Message2 =>
println("received message2")
otherActor ! Message1
case _ =>
}
}
}
}
lazy val actor1:Actor = new Actor1(actor2)
lazy val actor2:Actor = new Actor2(actor1)
Allerdings, wenn ich fügen Sie die folgende:
actor1.start
actor2.start
actor1 ! Message1
ich die folgende Fehlermeldung erhalten:
Exception in thread "main" java.lang.NoClassDefFoundError: com / fictitiousCompany / stackOverflowQuestion / Test Verursacht durch: java.lang.ClassNotFoundException: com.fictitiousCompany.stackOverflowQuestion.Test beim java.net.URLClassLoader $ 1.run (URLClassLoader.java:202) beim java.security.AccessController.doPrivileged (Muttersprache Verfahren) bei java.net.URLClassLoader.findClass (URLClassLoader.java:190) beim java.lang.ClassLoader.loadClass (ClassLoader.java:307) beim sun.misc.Launcher $ AppClassLoader.loadClass (Launcher.java:301) beim java.lang.ClassLoader.loadClass (ClassLoader.java:248)
Ich bin mit dem Scala Eclipse Plugin 2.8.1.
Lösung
Beachten Sie, dass auch Ihr kleineres Beispiel Probleme haben würde (in der REPL):
{
class A(b:B)
class B(a:A)
lazy val a:A = new A(b)
lazy val b:B = new B(a)
a
}
// causes stack overflow error
Sobald a
Bedürfnisse daher konstruiert ausgewertet werden, würde es erfordern, B, die A. für diese Arbeit a
oder b
Um erfordert hätte fertig gebaut.
Unter Verwendung von-namen Parametern ermöglicht es das kleinere Beispiel zu bewerten.
{
class A(b: => B)
class B(a: => A)
lazy val a:A = new A(b)
lazy val b:B = new B(a)
a
}
Beachten Sie sicher, ob das wird auch für die Schauspieler Beispiel arbeiten.
Edit: nach Namen params arbeitete lokal auf 2.8.0. Ich ersetzen Fall Klasse mit dem Objekt loszuwerden einigen deprecation Warnungen zu erhalten und hinzugefügt Startmethoden auf actor1, actor2 und trete das Ganze mit actor1 ! Message1
. Abgesehen davon habe ich Schauspieler noch nie benutzt, so dass ich nicht mehr kommentieren. Hier ist, was ich getestet:
import scala.actors._
abstract class Message
object Message1 extends Message
object Message2 extends Message
class Actor1(otherActor: => Actor) extends Actor {
def act() {
loop {
react {
case Message1 =>
println("received message1")
otherActor ! Message2
case _ =>
}
}
}
}
class Actor2(otherActor: => Actor) extends Actor {
def act() {
loop {
react {
case Message2 =>
println("received message2")
otherActor ! Message1
case _ =>
}
}
}
}
{
lazy val actor1:Actor = new Actor1(actor2)
lazy val actor2:Actor = new Actor2(actor1)
actor1.start
actor2.start
actor1 ! Message1
}
Gibt eine Reihe von:
received message1
received message2