懒惰val如何解决前向引用扩展到scala中的值定义



以下是取自scala第5章中fp的Stream类型的定义

sealed trait Stream[+A]
case object Empty                                   extends Stream[Nothing]
case class Cons[+A](h: () => A, t: () => Stream[A]) extends Stream[A]

我们可以编写以下方法,返回的无限流

def constant[A](a: A): Stream[A] = {
lazy val x: Stream[A] = Cons(() => a, () => x)
x
}

我不太明白的是,当x被定义为惰性val时,为什么编译器不抛出正向引用扩展到值的定义

我在这里找到了一个旧帖子:https://www.scala-lang.org/old/node/6502但仍在寻找一个明确的解释。

因为现在,正是由于您链接的帖子(AFAIK(,它是特别允许的:

声明或定义引入的名称的作用域是包含绑定的整个语句序列。然而,块中的前向引用有一个限制:在组成块的语句序列s1…sn中,如果si中的一个简单名称指的是由sj定义的实体,其中j≥i,则对于si和sj之间并包括si和sj的所有sk,

  • sk不能是变量定义。

  • 如果sk是一个值定义,它必须是惰性的

我不会详细介绍,也许这对你来说就足够了。。。它的工作原理和递归函数一样。惰性val的行为就像记忆函数。

此外,您也可以使它作为val工作,但它不能是局部变量。看到

class Test {
val a = 5
val x: Stream[Int] = Cons(() => a, () => x)
}

编译得很好。

最新更新