lazy val v.s.val用于Scala中的递归流



我了解vallazy val之间差异的基本原理。但是当我看到这个例子时,我感到困惑。

下面的代码是正确的。它是对流类型惰性值的递归。

def recursive(): {
     lazy val recurseValue: Stream[Int] = 1 #:: recurseValue.map(_+1) 
     recurseValue
}

如果我将lazy val更改为val。它报告错误。

def recursive(): {
     //error forward reference failed.
     val recurseValue: Stream[Int] = 1 #:: recurseValue.map(func) 
     recurseValue
}

我在第二个例子中通过替代模型/评估策略的思路是:

#:的右侧视线按名称调用,其值应为:

1 #:: ?

如果第2个元素随后被访问,则引用当前recurseValue值并将其重写为:

1 :: ((1 #:: ?) map func) = 1 :: (func(1) #:: (? map func))

等等,使得编译器应该成功。

我重写时没有看到任何错误,是不是出了什么问题?

编辑:结论:我发现如果val定义为一个域,它就可以工作。我还注意到了这篇关于val实现的帖子。结论是val在方法、字段或REPL上有不同的实现。这真是令人困惑。

如果您定义函数,则该替换模型适用于递归,但您不能根据变量本身来定义它,除非它是惰性的。计算右侧所需的所有信息都必须可用于进行赋值,因此需要一点惰性才能递归定义变量。

你可能并不真的想这么做,只是为了证明它适用于函数:

scala> def r = { def x:Stream[Int] = 1#::( x map (_+1) ); x }
r: Stream[Int] 
scala> r take 3 foreach println
1
2
3

相关内容

  • 没有找到相关文章

最新更新