gpt4 book ai didi

scala - 为什么 Scala 中的 block 内转发引用值必须是惰性的?

转载 作者:行者123 更新时间:2023-12-03 03:38:11 24 4
gpt4 key购买 nike

The scope of a name introduced by a declaration or definition is the whole statement sequence containing the binding. However, there is a restriction on forward references in blocks: In a statement sequence s[1]...s[n] making up a block, if a simple name in s[i] refers to an entity defined by s[j] where j >= i, then for all s[k] between and including s[i] and s[j],

  • s[k] cannot be a variable definition.
  • If s[k] is a value definition, it must be lazy.

编辑:我不确定 Mikaël Mayer 的回答是否真的解释了一切。考虑:

object Test {
def main(args: Array[String]) {
println(x)
lazy val x: Int = 6
}
}

这里,惰性值x在代码中实际定义之前肯定必须被读取/计算!这与 Mikaël 的主张相矛盾,即惰性求值消除了在定义事物之前对其求值的需要。

最佳答案

通常你不能这样:

val e: Int = 2
val a: Int = b+c
val b: Int = c
val c: Int = 1
val d: Int = 0

因为在定义 a 时,值 c 尚未定义。因为 a 引用 c,所以 a 和 c 之间的所有值都应该是惰性的,以避免依赖

val e: Int = 2
lazy val a: Int = b+c
lazy val b: Int = c
lazy val c: Int = 1
val d: Int = 0

这实际上将 a、b 和 c 翻译为对象,其值在读取时被初始化,这将在声明之后,即这相当于:

val e: Int = 2
var a: LazyEval[Int] = null
var b: LazyEval[Int] = null
var c: LazyEval[Int] = null
a = new LazyEval[Int] {
def evalInternal() = b.eval() + c.eval()
}
b = new LazyEval[Int] {
def evalInternal() = c.eval()
}
c = new LazyEval[Int] {
def evalInternal() = 1
}
val d = 0

其中 LazyEval 类似于以下内容(由编译器本身实现)

class LazyEval[T] {
var value: T = _
var computed: Boolean = false
def evalInternal(): T // Abstract method to be overriden
def eval(): T = {
if(computed) value else {
value = evalInternal()
computed = true
value
}
}
}

编辑

val 在 java 中并不真正存在。它们是局部变量或者在计算中不存在。因此,lazy val 的声明在任何事情完成之前就存在。请记住,闭包是在 Scala 中实现的。您的 block 将被重写为:

  object Test {    def main(args: Array[String]) {      // Declare all variables, val, vars.      var x: Lazy[Int] = null      // No more variables to declare. Lazy/or not variable definitions      x = new LazyEval[Int] {        def evalInternal() = 6      }      // Now the code starts      println(x)    }  }

关于scala - 为什么 Scala 中的 block 内转发引用值必须是惰性的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22615089/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com