首页 文章

斯卡拉懒惰的问题

提问于
浏览
1

我有一个场景,我有一些对象需要互相参考 . 我可以编译的唯一方法是使用 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 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 Plugin 2.8.1 .

1 回答

  • 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.为了使它能够工作 ab 必须完成构建 .

    使用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
    

相关问题