在定义定义之前的功能(正向参考扩展到变量的定义)

问题描述 投票:0回答:2
this Basic Scala示例代码:

object Test { def main(args: Array[String]) { inner() var x: Int = 5 def inner() { println("x: " + x) } } }
试图编译它会产生以下错误消息:

test.scala:3: error: forward reference extends over definition of variable x inner() ^ one error found

问题:

    在此上下文中的远期参考是什么,对它“扩展变量x的定义”是什么意思?
  1. 为什么以前的代码会引起此编译时错误?
  2. 该错误如何捕获?似乎编译器必须实现一些类似解释器的功能并关注函数调用!
  3. 这个问题实际上不是关于定义的顺序,而是何时调用函数。
  4. 在定义之前要调用函数是完全合法的 - 但是,如果在调用和函数定义之间放置一个变量,并且该函数使用此变量。 我喜欢此语言功能解释!为什么在那里?它如何工作?还有其他更复杂的示例 - 即,它只是其他功能的一部分还是某些规则的结果?
我认为编译器目前正在做什么:

检查函数是否是闭合,可以访问当前范围的变量, 检查实际上确实在当前范围中访问变量,并且

对于每个变量,闭合访问都会访问,请检查是否在调用之前定义了该变量

我基本上回答了我的第三个问题?这是这种行为的工作方式吗?这似乎使编译器很复杂(特别是如果我们考虑具有多个功能级别的病例)。

如果是这种情况,这如何集成到语言的形式定义中,即语法?在我看来,我编写的程序在语法上是正确的。

  1. Http://www.scala-lang.org/docu/files/scalareference.pdf
  2. 声明或定义引入的名称的范围是整个语句 包含结合的序列。但是,对向前有限制 块中的参考:在语句序列S1 ... sn组成一个块,如果简单 si中的名称是指由sj定义的实体,其中j> = i,然后介于两者之间的所有sk 包括SI和SJ,
•SK不能是可变定义。

•如果SK是一个值定义,则必须是懒惰的

此错误消息意味着不允许在块中进行正向参考。在一个块中,所有变量(或值)必须按线性顺序定义。
scala function variables scope
2个回答
6
投票

这将起作用: object Test { // forward reference is allowed in an object def inner() { println("x: " + x) } var x: Int = 5 }

这也将起作用:

class Test { // forward reference is allowed in an class def inner() { println("x: " + x) } var x: Int = 5 }

但这些都无法使用:


2
投票

由于val“ x”是一个字段初始化语句,因此在初始化之前将其引用是非法的(“ x”在初始化之前包含null)。

以使其正常工作,您可以将VAR更改为懒惰的Val:

def main() { // forward reference for lazy vals is allowed in a block def inner() { println("x: " + x) } lazy val x: Int = 5 }

法律示例,其中调用懒惰的val的方法在懒惰的val表达式之前被调用:
def main() { 
  inner()

  def inner() {
    println("x: " + x)
  }

  lazy val x: Int = 5
}

没有“ x”很懒惰,x”将被右开始,这打破了Scala编译器执行的重新检查阶段。
对于这种行为背后的一点点理论,您可以查看以下内容的“阶段refchecks”部分:
https://wiki.scala-lang.org/display/siw/siw/overview++feiw+compiler+compiler+plosees

	

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.