在定义函数之前调用函数(前向引用扩展到变量的定义) [英] Calling functions before they are defined (forward reference extends over definition of variable)

查看:64
本文介绍了在定义函数之前调用函数(前向引用扩展到变量的定义)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下基本的Scala示例代码:

Consider this basic Scala example code:

object Test {
    def main(args: Array[String]) {
        inner()

        var x: Int = 5

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

尝试对其进行编译会产生以下错误消息:

Trying to compile it produces the following error message:

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

问题:

  1. 在这种情况下,什么是前向引用?扩展变量x的定义"对它意味着什么?
  2. 为什么以前的代码会引发此编译时错误?
  3. 如何捕获此错误?似乎编译器必须实现一些类似于解释器的功能并遵循函数调用!

这个问题不是关于定义的顺序,而是关于何时调用函数.在定义函数之前先调用它是完全合法的-但是如果在调用和函数定义之间放置一个变量,并且该函数使用此变量,则突然变成非法.

This question is not really about the order of the definitions, but exactly when a function is called. It is completely legal for a function to be called before it is defined - but it suddenly becomes illegal if a variable is placed between the call and the function definition, and the function uses this variable.

我想解释一下此语言功能!为什么在那儿?它是如何工作的?还有其他更复杂的示例-即它仅仅是其他功能的一部分还是某些规则的结果?

I'd like this language feature explained! Why is it there? How does it work? Are there some other more complex examples - i.e. is it just a part of some other feature or a consequence of some rules?

我想象的编译器正在做什么:

What I imagine the compiler is currently doing:

  1. 检查该函数是否为可以访问当前作用域变量的闭包,
  2. 检查它是否确实访问了当前范围内的变量,并且
  3. 对于闭包访问的每个变量,请检查是否在调用之前定义了变量

我基本上回答了我的第三个问题吗?这是这种行为的方式吗?似乎使编译器变得非常复杂(特别是如果我们考虑具有多个功能级别的情况).

Did I basically answer my third question? Is this how this behavior works? It seems to complicate the compiler a lot (especially if we consider cases with multiple levels of functions).

如果是这样,它如何整合到语言的正式定义中,即语法?在我看来,我编写的程序在语法上是正确的.

If that is the case, how does this integrate into the formal definition of the language, i.e. the grammar? It seems to me that the program I wrote is grammatically correct.

推荐答案

来自 http://www.scala-lang.org/docu/files/ScalaReference.pdf :

由声明或定义引入的名称范围是整个语句包含绑定的序列.但是,对转发有限制块中的引用:在语句序列s1 ... sn中构成一个块,如果简单的话si中的名称是指由sj定义的实体,其中j> = i,然后对于和之间的所有sk包括si和sj,

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不能是变量定义.

• sk cannot be a variable definition.

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

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

这篇关于在定义函数之前调用函数(前向引用扩展到变量的定义)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆