For-Schleife [AHK_L 59+]

Führt für jedes Schlüssel-Wert-Paar eines Objekts wiederholt eine oder mehrere Anweisungen aus.

For Schlüssel , Wert in Ausdruck

Parameter

Schlüssel

Name der Variable, in der der Schlüssel zu Beginn jeder Wiederholung gespeichert werden soll.

Wert

Name der Variable, in der der Wert des aktuellen Schlüssels gespeichert werden soll.

Ausdruck

Ein Ausdruck, dessen Ergebnis ein Objekt ist, oder eine Variable, die ein Objekt enthält.

Bemerkungen

Ausdruck wird nur einmal vor Beginn der Schleife ausgewertet. Wenn das Ergebnis kein Objekt ist, springt die Ausführung sofort auf die Zeile nach dem Schleifenkörper; andernfalls wird die NewEnum()-Methode des Objekts zum Abrufen eines Enumerator-Objekts aufgerufen. Zu Beginn jeder Wiederholung wird die Next()-Methode des Enumerators zum Abrufen des nächsten Schlüssel-Wert-Paares verwendet. Wenn Next() eine leere Zeichenkette oder 0 zurückgibt, wird die Schleife terminiert.

Das folgende Beispiel zeigt die ungefähre Funktionsweise einer For-Schleife:

_enum := (Ausdruck)._NewEnum()
if IsObject(_enum)
    while _enum.Next(Schlüssel, Wert)
    {
        ...
    }

Existierende Schlüssel-Wert-Paare können während der Schleife geändert werden, aber das Einfügen oder Entfernen von Schlüsseln kann dazu führen, dass einige Elemente übersprungen oder mehrfach enumeriert werden. Um das zu umgehen, können Sie z.B. eine Liste der zu entfernenden Schlüssel erstellen und dann nach Abschluss der ersten Schleife eine zweite Schleife verwenden, um die Schlüssel zu entfernen. Beachten Sie, dass Sie mit Objekt.Remove(ErsterSchlüssel, LetzterSchlüssel) einen Bereich von Schlüsseln entfernen können, ohne dass eine Schleife notwendig ist.

Nach einer For-Schleife folgt üblicherweise ein Block, eine Sammlung von Anweisungen, die den Körper der Schleife bilden. Für eine Schleife mit nur einer einzigen Anweisung ist jedoch kein Block erforderlich (ein "if" und dessen "else" werden in diesem Fall als Einzelanweisung behandelt). Der One True Brace (OTB) Style wird unterstützt, d.h. Sie können je nach Bedarf die geschweifte Startklammer am Zeilenende positionieren. Zum Beispiel: for x, y in z {.

Wie bei allen Schleifen können Break, Continue und A_Index verwendet werden.

COM-Objekte

Da Schlüssel und Wert direkt an die Next()-Methode des Enumerators übergeben werden, hängen die zugewiesenen Werte davon ab, welche Art von Objekt enumeriert wird. Handelt es sich um ein COM-Objekt, enthält Schlüssel den Rückgabewert von IEnumVARIANT::Next() und Wert eine Zahl, die seinen Variantentyp repräsentiert. Zum Beispiel wird bei Verwendung eines Scripting.Dictionary-Objekts jeder Schlüssel einen Schlüssel aus dem Dictionary enthalten und Wert typischerweise 8 für Zeichenketten und 3 für Integer sein. Eine Auflistung aller Typennummern finden Sie unter ComObjType().

[v1.0.96.00+]: Beim Enumerieren eines SafeArrays enthält Schlüssel das aktuelle Element und Wert seinen Variantentyp.

Enumerator-Objekt, Objekt._NewEnum(), While-Schleife, Loop, Until, Break, Continue, Blöcke

Beispiele

Listet die Schlüssel-Wert-Paare eines Objekts auf.

Farben := Object("Rot", 0xFF0000, "Blau", 0x0000FF, "Grün", 0x00FF00)
; "Farben" könnte direkt mit dem obigen Ausdruck ersetzt werden:
For k, v in Farben
    s .= k "=" v "`n"
MsgBox % s

Listet alle geöffneten Explorer- und Internet-Explorer-Fenster unter Nutzung des Shell-Objekts auf.

for window in ComObjCreate("Shell.Application").Windows
    windows .= window.LocationName " :: " window.LocationURL "`n"
MsgBox % windows

Klasse: CEnumerator

Stellt ein generisches Enumerator-Objekt bereit, mit dem numerische Schlüssel iteriert werden können. Das Array darf beim Iterieren nicht verändert werden, da sonst der iterierte Bereich ungültig wäre. Es ist möglich, benutzerdefinierte MaxIndex()-Funktionen für die Array-Grenzen zu definieren. Befinden sich fehlende Array-Elemente zwischen 1 und Max-Index, werden sie iteriert, aber einen Wert von "" haben. Das bedeutet, dass dieser Enumerator konzeptbedingt keine echten lückenhaften Arrays unterstützt. Quelle: Suggestions on documentation improvements

/*
Klasse: CEnumerator

Damit ein Objekt diesen Iterator verwenden kann, fügen Sie diese Funktion in die Klassendefinition ein:

    _NewEnum()
    {
    	return new CEnumerator(this)
    }
*/

; Iteriert über den Enumerator
For k, v in Test
    MsgBox %k%=%v%

; Testklasse zur Demonstration der Verwendung
class Test
{
    static Data := ["abc", "def", "ghi"]

    _NewEnum()
    {
        return new CEnumerator(this.Data)
    }
}

class CEnumerator
{
    __New(Object)
    {
        this.Object := Object
        this.first := true
        ; Für die Geschwindigkeit zwischenspeichern. Nützlich, falls benutzerdefinierte MaxIndex()-Funktionen schlechte Performanz haben.
        ; Das bedeutet aber auch, dass beim Iterieren keine Schlüssel-Wert-Paare eingefügt werden können, da sonst der Bereich ungültig wäre.
        this.ObjMaxIndex := Object.MaxIndex()
    }

    Next(ByRef key, ByRef value)
    {
        if (this.first)
        {
            this.Remove("first")
            key := 1
        }
        else
            key ++
        if (key <= this.ObjMaxIndex)
            value := this.Object[key]
        else
            key := ""
        return key != ""
    }
}