gpt4 book ai didi

scala - Scala 中惰性值的范围规则是什么?

转载 作者:行者123 更新时间:2023-12-01 09:00:28 24 4
gpt4 key购买 nike

我正在阅读 sbt 文档,我在多项目构建部分遇到了这个示例:

import sbt._
import Keys._

object HelloBuild extends Build {
lazy val root = Project(id = "hello",
base = file(".")) aggregate(foo, bar)

lazy val foo = Project(id = "hello-foo",
base = file("foo"))

lazy val bar = Project(id = "hello-bar",
base = file("bar"))
}

我想知道如何在声明 foo 和 bar 之前引用它们?我认为这与lazy 关键字有关,但是从我的阅读中,我认为lazy 关键字只是延迟了初始化?似乎这里的值甚至在声明之前就在范围内,更不用说初始化......

希望有人能够解释这里发生了什么!

最佳答案

参见 Scala language specification 的第 4 章:

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 s1 ... sn making up a block, if a simple name in si refers to an entity defined by sj where j ≥ i, then for all sk between and including si and sj,

  • sk cannot be a variable definition.
  • If sk is a value definition, it must be lazy.

换句话说:您可以对惰性 val 进行前向引用,但前提是它们之间没有 var 或非惰性 val。如果你认为惰性 val 更像是一个方法而不是一个变量,这有点直观,并通过 REPL 上的两个快速示例:

scala> object o { val a = b; lazy val c = 6; lazy val b = c }
defined module o

scala> o.a
res1: Int = 6

在第一个示例中,Scala 通过调用 b 来计算 a,而 b 又调用 c,其计算结果为 6。但在下一个例子中,当 c 不懒惰时...

scala> object o { val a = b; val c = 6; lazy val b = c }
defined module o

scala> o.a
res2: Int = 0

当 Scala 计算 a 时,它调用 b,返回 c 的当前值(当时是 0 ,JVM 的整数默认值,因为 c 尚未初始化)。 那么 c 之后会被初始化,但是到那时已经来不及了。

另请参阅:How are lazy val class variables implemented in Scala 2.10?

关于scala - Scala 中惰性值的范围规则是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18009160/

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