java - 在 for 循环声明中初始化的变量的范围实际上不仅仅是 block 范围吗?

标签 java c# for-loop scope language-agnostic

考虑一个 for用计数器循环:

for (int i = 0; i < 100; i++ /* `i` is visible here */) {
    /* `i` is visible here */
}
/* `i` not visible here */

一切顺利。 We say that i has "block" scope.

但是,为什么在for中声明的变量呢?在 i++ 处无法访问循环?

例如,为什么是j不在此处的范围内,当它也具有“ block ”范围并且在 i += j 之前的时间段内声明时?

for (int i = 0; i < 100; i += j /* only `i` is visible here */) {
    int j = 1;
    /* `i` and `j` are visible here */
}
/* `i` and `j` are not visible here */

我看到很多关于 i 范围的问题, 但与 j 的范围无关在 for 内循环括号。这是否意味着在技术上还有另一个没有人谈论的范围,即“for 循环声明范围”?如果是这样,我感兴趣的是这个范围在 Java 或 C# 等规范中是如何定义的,以及它通常被程序员称为什么范围。

编辑:是的,我知道我可以将循环声明为 for (int j, i = 0; i < 100; i += j) ,但这仍然表明 for循环声明的作用域比它们的花括号更大。

最佳答案

面部原因JLS 6.3以这种方式指定范围:

The scope of a local variable declared in the ForInit part of a basic for statement (§14.14.1) includes all of the following:

  • Its own initializer
  • Any further declarators to the right in the ForInit part of the for statement
  • The Expression and ForUpdate parts of the for statement
  • The contained Statement

for 主体的“包含语句”。 for 主体中定义的变量没有特殊的范围规则。正常规则适用。 (它们也在 JLS 6.3 中。)


这种语言设计背后的原因包括(我猜想1)以下几点:

  • 如果您必须在循环体内查看声明2 的变量,那么可读性会很差。
  • 确定循环中声明的变量是否已明确初始化的逻辑很难指定,程序员也很难理解。示例:

    for (i = 1; i < 10; i = i + j) {
        int j;
        if (i > 3) {
            j = 42;
        }
        // do stuff
    }
    

1 - 真正的原因只有 C 语言的设计者才知道……在 1970 年代。我怀疑 Java 设计者是否考虑过与 C 不同的做法。他们试图让 Java “像 C”。

2 - 循环体中的某些内容可能会修改循环变量,这已经够糟糕了。 :-(

关于java - 在 for 循环声明中初始化的变量的范围实际上不仅仅是 block 范围吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37892846/

相关文章:

java - 有条件的内部 for 循环还是大量的 for 循环?

java - 从 mp3 文件中读取标签

java - 多参数输入字符串

c# - CA1404 - 尽管语句前面有 return 子句,CA2000 - 尽管没有进一步的引用用法

javascript - Javascript SyntaxError : missing ; before statement (after for loop)

ios - 表达式结果未在for循环中使用

java - Char* 在 JNI 调用中损坏

java - 无法暂停我的线程!为什么?

c# - 在 C# 中使用正则表达式更改字符串(基于 ActionScript 函数)

c# - 最大声级是多少