斯卡拉惰性Val问题

问题描述:

我有一个场景,我有一些对象需要在彼此的引用。我能得到这个编译的唯一方法就是使用斯卡拉惰性Val问题

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 

我得到以下错误:

Exception in thread "main" java.lang.NoClassDefFoundError: com/fictitiousCompany/*Question/Test Caused by: java.lang.ClassNotFoundException: com.fictitiousCompany.*Question.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。

+0

我怀疑有关于不被Eclipse的正确设置classpath中一个单独的问题。您可能想要尝试命令行`scala -cp classes com.fictitious.*Question.Test`,其中类指向生成的类文件。 – huynhjl 2011-01-19 04:02:25

+0

这很奇怪,我可以在这之前编写一些相对复杂的代码,而没有使用Eclipse的任何问题。我的其他代码仍然运行。也许这是一个Eclipse插件错误...? – 2011-01-19 04:24:43

请注意,即使你的小例子就是有问题(在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.为了这个工作ab将不得不完成构建。

使用名称参数允许较小的示例进行评估。

{ 
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本地工作。我用对象替换案例类以摆脱一些弃用警告,并在actor1,actor2上添加启动方法,并用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