我有一个场景,我有一些对象需要互相引用。我可以编译的唯一方法是使用 lazy
class A(b:B)
class B(a:A)
lazy val a:A = new A(b)
lazy val b:B = new B(a)
我可以使用一些演员做同样的事情,并让它也可以编译
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)
但是,当我添加以下内容时:
actor1.start
actor2.start
actor1 ! Message1
我收到以下错误:
线程“main”中的异常 java.lang.NoClassDefFoundError: COM / fictitiousCompany / stackOverflowQuestion /测试 引起: 抛出java.lang.ClassNotFoundException: com.fictitiousCompany.stackOverflowQuestion.Test 在 java.net.URLClassLoader的$ 1.run(URLClassLoader.java:202) 在 java.security.AccessController.doPrivileged(母语 方法)at java.net.URLClassLoader.findClass(URLClassLoader.java:190) 在 java.lang.ClassLoader.loadClass(ClassLoader.java:307) 在 sun.misc.Launcher $ AppClassLoader.loadClass(Launcher.java:301) 在 java.lang.ClassLoader.loadClass(ClassLoader.java:248)
我正在使用Scala Eclipse插件2.8.1。
答案 0 :(得分:11)
请注意,即使是较小的示例也会出现问题(在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
一旦a
需要进行评估,它就需要B,这需要A.为了使其工作a
或b
必须完成构建
使用by-name参数可以评估较小的示例。
{
class A(b: => B)
class B(a: => A)
lazy val a:A = new A(b)
lazy val b:B = new B(a)
a
}
请注意,这是否也适用于您的演员示例。
编辑:按名称params在2.8.0本地工作。我用对象替换了case类来删除一些弃用警告,并在actor1,actor2上添加了start方法,并用actor1 ! Message1
踢了整个东西。除此之外,我之前没有使用演员,所以我不能评论更多。这是我测试的:
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
}
打印一堆:
received message1
received message2