Scala Lazy Val 问题
我有一个场景,我有一些对象需要相互引用。我可以编译它的唯一方法是使用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/Test 造成原因: java.lang.ClassNotFoundException: com.fictitiousCompany.stackOverflowQuestion.Test 在 java.net.URLClassLoader$1.run(URLClassLoader.java:202) 在 java.security.AccessController.doPrivileged(本机 方法)在 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。
I have a scenario where I have some objects that need to take in references from each other. The only way I can get this to compile is to use lazy
class A(b:B)
class B(a:A)
lazy val a:A = new A(b)
lazy val b:B = new B(a)
I can do the same thing using some actors, and get it to compile also
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)
However, when I add the following:
actor1.start
actor2.start
actor1 ! Message1
I get the following error:
Exception in thread "main"
java.lang.NoClassDefFoundError:
com/fictitiousCompany/stackOverflowQuestion/Test
Caused by:
java.lang.ClassNotFoundException:
com.fictitiousCompany.stackOverflowQuestion.Test
at
java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at
java.security.AccessController.doPrivileged(Native
Method) at
java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at
java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at
sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at
java.lang.ClassLoader.loadClass(ClassLoader.java:248)
I'm using the Scala Eclipse Plugin 2.8.1.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
请注意,即使您的较小示例也会出现问题(在 REPL 中):
一旦需要评估
a
并构建它,它就需要 B,而 B 又需要 A。为了使其正常工作a
或b
必须完成构造。使用按名称参数可以对较小的示例进行评估。
请注意,这是否也适用于您的演员示例。
编辑:按名称参数在 2.8.0 上本地工作。我用 object 替换了 case 类,以消除一些弃用警告,并在 actor1、actor2 上添加了启动方法,并使用 actor1 来踢掉整个事情!消息1。除此之外,我之前没有使用过 actor,所以我无法发表更多评论。这是我测试的:
打印一堆:
Note that even your smaller example would have issues (in the REPL):
As soon as
a
needs to be evaluated therefore constructed, it would require B, which requires A. In order for this to worka
orb
would have to finish being constructed.Using by-name parameters allows the smaller example to evaluate.
Note sure if that'll work for your actor example as well.
Edit: by name params worked locally on 2.8.0. I replaced case class with object to get rid of some deprecation warnings and added start methods on actor1, actor2 and kick the whole thing with
actor1 ! Message1
. Aside from this I haven't used actor before, so I can't comment more. Here is what I tested:Prints a bunch of: