斯卡拉懒惰瓦尔问题 [英] Scala Lazy Val Question
问题描述
我有一个场景,其中有一些对象需要彼此引用.我可以编译的唯一方法是使用 lazy
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)
我可以使用一些actor来做同样的事情,并且还可以对其进行编译
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
我收到以下错误:
线程主"中的异常 java.lang.NoClassDefFoundError: com/fictitiousCompany/stackOverflow问题/测试 造成原因: 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)
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)
我正在使用Scala Eclipse插件2.8.1.
I'm using the Scala Eclipse Plugin 2.8.1.
推荐答案
请注意,即使您的示例较小,也会出现问题(在REPL中):
Note that even your smaller example would have issues (in the 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
必须完成构造.
As soon as a
needs to be evaluated therefore constructed, it would require B, which requires A. In order for this to work a
or b
would have to finish being constructed.
使用名称参数可以评估较小的示例.
Using by-name parameters allows the smaller example to evaluate.
{
class A(b: => B)
class B(a: => A)
lazy val a:A = new A(b)
lazy val b:B = new B(a)
a
}
请注意,该方法是否同样适用于您的演员实例.
Note sure if that'll work for your actor example as well.
按名称,params在2.8.0上本地工作.我用对象替换了case类以摆脱一些过时的警告,并在actor1,actor2上添加了start方法,并用actor1 ! Message1
插入了整个内容.除此之外,我以前没有使用过actor,所以我无法发表更多评论.这是我测试的内容:
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:
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
这篇关于斯卡拉懒惰瓦尔问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!