6

为什么 Java、C 和 C++(可能还有其他语言)不允许在 for 循环变量上使用一种以上的类型?例如:

for (int i = 0; i < 15; i++)

在这种情况下,我们有一个循环变量 i,它是循环计数器。

但我可能想要另一个变量,其范围仅限于循环,而不是每次迭代。例如:

for (int i = 0, variable = obj.operation(); i < 15; i++) { ... }

我将obj.operation()返回数据存储在其中,variable因为我只想在循环中使用。我不想variable被保存在内存中,也不想在循环执行后保持可见。不仅可以释放内存空间,还可以避免因错误使用variable.

因此,循环变量很有用,但由于其类型限制而没有得到广泛支持。想象一下,该operation()方法返回一个 long 值。如果发生这种情况,我将无法在不强制转换和丢失数据的情况下享受循环变量的优势。以下代码无法在 Java 中编译:

for (int i = 0, long variable = obj.operation(); i < 15; i++) { ... }

同样,有人知道为什么存在这种类型限制吗?

4

6 回答 6

21

存在此限制是因为您的要求相当不寻常,并且可以通过非常相似(并且只是稍微详细一点)的构造来获得。如果您真的想这样做,Java 支持匿名代码块来限制范围:

public void method(int a) {
  int outerVar = 4;
  {
    long variable = obj.operation();
    for (int i = 0; i < 15; i++) { ... }
  }
}
于 2009-08-26T21:05:17.913 回答
6

你的例子:

for (int i = 0, long variable = obj.operation(); i < 15; i++) { ... }

是非法的,原因相同:

int i = 0, long variable = obj.operation();

本身就是非法的。逗号不会开始新的语句。逗号前后的两个部分都是一个语句的一部分。该语句声明和初始化一个int变量列表。好吧,int无论如何,这就是行首的标识符告诉编译器的内容。逗号后面的long标识符是错误的,因为要声明不同类型的变量,你必须开始一个新的语句。

由于您不能在一个语句中声明两种不同类型的变量,因此您必须在for初始化程序之外声明其中一个。

于 2009-08-27T01:30:16.547 回答
2

好吧,语法是 for( expr ; expr ; expr ),你不能在一个表达式中声明两个不同类型的变量。所以它与循环变量没有太大关系。

于 2009-08-26T21:08:09.327 回答
1

@jsight 是对的,但我认为真正的原因是语法简单。假设 Java 允许在第一个逗号之后使用类型或新变量名。由于 Java 不需要前向声明,因此逗号后面的标识符可以是一个新的变量名,一个以前没有遇到过的 Class 名称的现有类名。现在应该可以解决这个问题了,但是:

  1. 它使语法更复杂,可能以不立即显而易见的方式。
  2. 它使 Java 编译器的解析阶段更加复杂。
  3. 它使处理 Java 源代码的其他工具变得更加复杂。
  4. 如果 for 循环中存在语法错误,它可能会导致更模糊和/或误导性的编译器错误消息。

(IMO,语法复杂性是 C 尤其是 C++ 的缺点之一。我在这两种语言中都做了很多编码,但我仍然发现语法错误消息有时难以解码。)

于 2009-08-27T01:07:06.170 回答
0

只是猜测 - 在循环中声明“长变量”非常简单,而且由于 Java 旨在简单,设计人员可能认为没有必要添加对您想要的内容的支持。

于 2009-08-26T21:06:23.137 回答
0

根据规范,for 语句的初始化可以是被评估和丢弃的语句表达式列表,也可以是单个变量声明语句。一个变量声明语句可以声明多个变量,但它们都属于同一类型。

所以你可以这样做:

for (int i = 0, variable = obj.operation(); i < 15; i++) { ... }

但在这种情况下,变量将被定义为 int。

于 2009-08-26T21:21:02.793 回答