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()リターンデータを格納しています。メモリに保持したくないし、ループ実行後も表示されたままにしたくない。メモリスペースを解放するだけでなく、の誤った使用によって引き起こされる望ましくない動作を回避するためにも。variablevariablevariable

したがって、ループ変数は便利ですが、型の制限があるため、広くサポートされていません。operation()そのメソッドが長い値を返すと想像してください。これが発生した場合、データをキャストして失うことなく、ループ変数の利点を享受することはできません。次のコードは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();

それ自体は違法です。カンマは新しいステートメントを開始しません。コンマの前後の両方の部分は、1つのステートメントの一部です。intこのステートメントは、変数のリストを宣言して初期化しています。とにかく、それは行の先頭にあるint識別子がコンパイラに伝えるものです。カンマの後のlong識別子はエラーです。別のタイプの変数を宣言するには、新しいステートメントを開始する必要があります。

1つのステートメントで2つの異なるタイプの変数を宣言することはできないため、forイニシャライザーの外部でそれらの1つを宣言する必要があります。

于 2009-08-27T01:30:16.547 に答える
2

構文はfor(expr ; expr ; expr)であり、1つの式で異なるタイプの2つの変数を宣言することはできません。したがって、ループ変数とはあまり関係がありません。

于 2009-08-26T21:08:09.327 に答える
1

@jsightは正しいですが、本当の理由は構文の単純さだと思います。Javaが最初のコンマに続く型または新しい変数名のいずれかを許可したと仮定します。Javaは前方宣言を必要としないため、コンマに続く識別子は新しい変数名、つまり以前に遭遇したことのないクラスの名前の既存のクラス名である可能性があります。これでこれに対処できるはずですが、次のようになります。

  1. それは、おそらくすぐには明らかではない方法で、文法をより複雑にします。
  2. これにより、Javaコンパイラの解析フェーズがより複雑になります。
  3. これにより、Javaソースコードを処理する他のツールのライブがより複雑になります。
  4. forループに構文エラーがあると、コンパイラのエラーメッセージがより曖昧になったり誤解を招いたりする可能性があります。

(IMO、構文の複雑さはC、特にC ++の失敗の1つです。両方で多くのコーディングを行いましたが、構文エラーメッセージをデコードするのが難しい場合があります。)

于 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 に答える