Scala error: “forward reference extends over definition of value” when code appears in a function

。_饼干妹妹 提交于 2019-12-04 22:03:19

There was an answer here, but it was deleted for some reason.

There are basically two options. You could make your val into lazy val. Or you could define your lucas: Stream[Int] in a class as a field. You can parameterize the class with p and q in the constructor.

You are right that the original code is lazy. But it is not lazy enough for scala to translate it.

For the sake of simplicity think into what code val a = 1 + a will be translated (I know the code does not make sense much). In Java int a = 1 + a won't work. Java will try to use a in 1 + a, but a is not yet initialized. Even if Java had Integer a = 1 + a, and a would be a reference, Java still not able to execute this, because Java runs 1 + a statement when allocating a

So it leaves us with two options. Defining a not as a variable, but as a field. Scala automatically resolve the problem by defining a recursive method, instead of a field - because field in scala is two methods + variable anyway. Or you could tell scala explicitly that it should resolve the lazy problem here by specifying your val as lazy val. This will make scala generate a hidden class with all the necessary infrastructure for it to be lazy.

You can check this behavior by running your compiler with -print option. The output is rather complicated though, especially in lazy val case.

Also please note that because your stream leaves the scope and also because you have two parameters for your stream - p and q, your stream will be recomputed each call if you go with lazy val option. If you choose creating an additional class - you are able to control this, by caching all instances of this class for each p and q possible

P.S. By saying Java here I of course mean JVM. It just easier to think in terms of Java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!