在Scala中,何时需要指定惰性?

在Scala中,何时需要指定惰性?,scala,lazy-evaluation,Scala,Lazy Evaluation,在本地Scala REPL中,可以定义流和惰性列表,而不使用关键字lazy scala> val fibo: LazyList[BigInt] = (0: BigInt) #:: (1: BigInt) #:: fibo.zip(fibo.tail).map { n => n._1 + n._2 } fibo: LazyList[BigInt] = LazyList(<not computed>) scala> fibo(100) res17: BigInt =

在本地Scala REPL中,可以定义流和惰性列表,而不使用关键字
lazy

scala> val fibo: LazyList[BigInt] = (0: BigInt) #:: (1: BigInt) #:: fibo.zip(fibo.tail).map { n => n._1 + n._2 }
fibo: LazyList[BigInt] = LazyList(<not computed>)

scala> fibo(100)
res17: BigInt = 354224848179261915075

scala> val prime: LazyList[Int] = 2 #:: LazyList.from(3).filter(i => prime.takeWhile {
     |    j => j * j <= i
     | }.forall {
     |    k => i % k != 0
     | })
prime: LazyList[Int] = LazyList(<not computed>)

scala> prime(100)
res18: Int = 547
但事实并非如此

错误:(21,67)正向引用扩展到值
prime

val prime:LazyList[Int]=2#:::LazyList.from(3).filter(i=>prime.takeWhile{

错误:(32,43)正向引用扩展到值的定义
fibo

val-fibo:LazyList[Int]=0:1:fibo.zip(fibo.tail).map(n=>n.\u 1+n.\u 2)

将它们标记为懒惰将清除错误

我知道REPL中有些东西的工作方式不同,但我不明白为什么会出现这种情况。我可能在这里遗漏了一些微妙之处,但为什么不省略“
懒惰”
”在REPL中会导致前向引用错误。一般来说,什么时候需要明确指定惰性,以及为什么?

这不是“在REPL中工作方式不同”的直接“原因之一”,但这是因为它们。在失败的代码中,
prime
fibo
是局部变量。当您直接在REPL中定义它们时,它们是匿名对象的属性,即它生成类似

object Line1 {
  val fibo = ...
}
import Line1.fibo
如果您查看规范,则仅适用于局部变量:

它可以构成对象或类定义的一部分,也可以是块的局部

但是,对块中的前向引用有限制

object Line1 {
  val fibo = ...
}
import Line1.fibo