2009-08-26 6 views
3

Warum erlauben Java, C und C++ (vielleicht auch andere Sprachen) nicht mehr als einen Typ für For-Loop-Variablen? Zum Beispiel:Typeinschränkung in Schleifenvariablen in Java, C und C++

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

In diesem Fall haben wir eine Schleifenvariable i, die der Schleifenzähler ist.

Aber ich möchte vielleicht eine andere Variable haben, deren Umfang auf die Schleife beschränkt ist, nicht auf jede Iteration. Zum Beispiel:

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

Ich Speicherung obj.operation() Rückgabedaten in variable, weil ich es benutzen will nur innerhalb der Schleife. Ich möchte nicht variable im Speicher gehalten werden, noch nach der Ausführung der Schleife sichtbar bleiben. Nicht nur, um Speicherplatz freizugeben, sondern auch um unerwünschtes Verhalten zu vermeiden, das durch die falsche Verwendung von variable verursacht wird.

Daher sind Schleifenvariablen nützlich, werden aber aufgrund ihrer Typbeschränkung nicht umfassend unterstützt. Stellen Sie sich vor, dass Methode einen langen Wert zurückgibt. Wenn das passiert, kann ich die Vorteile von Schleifenvariablen nicht genießen, ohne Daten zu werfen und zu verlieren. Der folgende Code kompiliert nicht in Java:

Wieder jemand weiß, warum diese Art der Einschränkung existiert?

Antwort

20

Diese Einschränkung besteht, weil Ihre Anforderung ziemlich ungewöhnlich ist und mit einem sehr ähnlichen (und nur etwas ausführlicheren) Konstrukt gewonnen werden kann. Java unterstützt anonyme Code-Blöcke Umfang zu beschränken, wenn Sie das wirklich tun mögen:

public void method(int a) { 
    int outerVar = 4; 
    { 
    long variable = obj.operation(); 
    for (int i = 0; i < 15; i++) { ... } 
    } 
} 
+0

das ist was ich wollte. funktioniert auch auf C/C++. Danke! wenn ich könnte würde ich +1 geben;) – fjsj

+0

Die Antwort funktioniert, aber mit anonymen Blöcken wie das ist ein ungewöhnlicher Stil, würde ich das nicht in meinen Programmen verwenden. – Jesper

+0

Ich begegne dieser Einschränkung sehr häufig, zum Beispiel wenn ich einen Iterator oder eine andere sequentielle Struktur basierend auf dem Index transformieren muss. Init-Klausel der for-Schleife ist ein guter Ort, um Variablen, die nur im Kontext dieser Schleife benötigt werden, zu setzen. Zum Beispiel wäre dies eine gute Schleife, um ein zufälliges Array zu füllen: für (int i = 0, final Zufällig zufällig = neu Zufällig(); i Fixpoint

0

nur raten - es ist so einfach, „long Variable“ innerhalb der Schleife zu erklären, und da Java ist auf Einfachheit ausgerichtet, die Designer Möglicherweise ist es nicht notwendig, dass Sie Unterstützung für das hinzufügen, was Sie möchten.

+1

Dies wird die Variable pro Iteration, nicht pro Schleife – Jesse

+0

Geltungsbereich Wie Jesse sagte, ich interessiere mich für Loop-Bereich. Ich möchte den Variablenwert nicht bei jeder Iteration verlieren. – fjsj

2

Nun, ist die Syntax für (ausdr; ausdr; ausdr) und Sie können nicht zwei Variablen verschiedenen Typen in einem Ausdruck deklarieren. Es hat also nicht viel mit loop Variable zu tun.

+1

Nein, das ist in Java legal: für (int i = 0, j = 5; i

+0

Ähm, ich nehme das zurück. Ich glaube, ich habe deinen Kommentar falsch gelesen. –

0

Gemäß der specification kann die Initialisierung der for-Anweisung eine Liste von Anweisungsausdrücken sein, die ausgewertet und verworfen werden, oder eine einzelne Deklarationsanweisung. Eine Variablendeklarationsanweisung kann mehrere Variablen deklarieren, die alle vom selben Typ sind.

So könnten Sie dies tun:

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

Aber Variable würde als int in diesem Fall definiert werden.

+1

Ich bin mir dessen bewusst, aber ich möchte mehr als eine Variable mit verschiedenen Typen deklarieren. – fjsj

1

@jsight hat recht, aber ich denke der wahre Grund ist syntaktische Einfachheit. Angenommen, Java hat nach dem ersten Komma entweder einen Typ oder einen neuen Variablennamen erlaubt. Da Java keine Vorwärtsdeklaration erfordert, könnte ein Bezeichner, der auf das Komma folgt, ein neuer Variablenname sein, ein vorhandener Klassenname des Namens einer Klasse, die zuvor nicht gefunden wurde.Nun sollte es möglich sein, sich damit zu befassen, aber:

  1. Es macht die Grammatik komplexer, möglicherweise in einer Weise, die nicht sofort offensichtlich sind.
  2. Es macht die Parse-Phase des Java-Compilers komplexer.
  3. Es macht das Leben komplizierter für andere Werkzeuge, die Java-Quellcode verarbeiten.
  4. Es führt wahrscheinlich zu mehr vagen und/oder irreführenden Compiler-Fehlermeldungen, wenn in einer for-Schleife ein Syntaxfehler vorliegt.

(IMO, syntaktische Komplexität ist eine der Schwächen von C und insbesondere C++. Ich habe eine Menge Codierung in beide getan haben, aber ich habe noch die Syntaxfehlermeldungen schwer manchmal zu entschlüsseln.)

3

Ihr Beispiel:

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

aus dem gleichen Grund illegal ist, dass:

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

selbst illegal wäre. Das Komma startet keine neue Anweisung. Beide Teile vor und nach dem Komma sind Teil einer Aussage. Diese Anweisung deklariert und initialisiert eine Liste von int Variablen. Nun, das ist, was die int Kennung am Anfang der Zeile den Compiler sowieso sagt. Der long Bezeichner nach dem Komma ist ein Fehler, da Variablen von einem anderen Typ deklariert werden müssen, müssen Sie eine neue Anweisung starten.

Da Sie Variablen von zwei verschiedenen Typen nicht in einer Anweisung deklarieren können, müssen Sie eine davon außerhalb des Initialisierers for deklarieren.