For-Schleife [AHK_L 59+]

Führt für jedes Key-Value-Paar eines Objekts eine Reihe von Befehlen wiederholend aus.

For Key , Value in Ausdruck

Parameter

Key

Name der Variable, in der der Key zu Beginn jeder Iteration (Wiederholung) gespeichert werden soll.

Value

Name der Variable, in der der Wert des aktuellen Keys gespeichert werden soll.

Ausdruck

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

Bemerkungen

Ausdruck wird nur einmal ausgewertet, bevor die Schleife beginnt. Wenn das Ergebnis des angegebenen Ausdrucks kein Objekt ist, wird der Schleifenkörper übersprungen und die nächste ausführbare Zeile angesteuert; ansonsten wird die NewEnum()-Methode des Objekts aufgerufen, um an dessen Enumerator-Objekt zu gelangen. Zu Beginn jeder Iteration wird die Next()-Methode des Enumerators aufgerufen, um das nächste Key-Value-Paar zu ermitteln. Wenn Next() eine 0 oder eine leere Zeichenkette zurückgibt, wird die Schleife beendet.

Das folgende Beispiel zeigt, wie eine For-Schleife ungefähr abläuft:

_enum := (Ausdruck)._NewEnum()
if IsObject(_enum)
    while _enum.Next(Key, Value)
    {
        ...
    }

Bestehende Key-Value-Paare können während der Schleife geändert werden. Allerdings kann das Einfügen oder Entfernen von Keys dazu führen, dass einige Elemente mehrfach übersprungen oder enumeriert werden. Eine Möglichkeit, dies zu umgehen, wäre es, eine Liste mit Keys zu erstellen, die entfernt werden sollen, und danach eine zweite Schleife zu verwenden, um die Keys nach dem ersten Schleifendurchlauf zu entfernen. Mit Object.Remove(ErsterKey, LetzterKey) kann ein bestimmter Bereich von Keys entfernt werden, ohne dass eine Schleife notwendig ist.

Nach einer For-Schleife erfolgt üblicherweise ein Block (eine Sammlung von Anweisungen), der den Schleifenkörper definiert. Eine Schleife mit nur einer einzigen Anweisung benötigt keinen Block (ein "if" und das dazugehörige "else" werden hierbei als Einzelanweisung angesehen). Optional kann der "One True Brace Style" (OTB) angewendet werden, um die geschweifte Startklammer auf dieselbe Zeile statt darunter zu setzen. Zum Beispiel: for x, y in z {.

Diese und jede andere Schleife in AutoHotkey kann auf Hilfsmittel wie Break, Continue und A_Index zurückgreifen.

COM-Objekte

Da Key und Value 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 Key den Rückgabewert von IEnumVARIANT::Next() und Value eine Zahl, die seinen Variantentyp repräsentiert. Wenn es zum Beispiel mit einem Scripting.Dictionary-Objekt genutzt wird, enthält Key einen Key aus dem Dictionary und Value eine 8 für Zeichenketten und eine 3 für Integer. Auf der ComObjType-Seite finden Sie eine Auflistung aller Typennummern.

[v1.0.96.00+]: Beim Enumerieren eines SafeArrays enthält Key das aktuelle Element und Value seinen Variantentyp.

Siehe auch

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

Beispiele

; Listet die Key-Value-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 offenen Explorer- und IE-Fenster auf:
for window in ComObjCreate("Shell.Application").Windows
    Fenster .= window.LocationName " :: " window.LocationURL "`n"
MsgBox % Fenster
/*
Klasse: CEnumerator

Generisches Enumerator-Objekt, mit dem numerische Keys iteriert werden können.
Das Array darf beim Iterieren nicht verändert werden, weil der iterierte Bereich ansonsten 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 keine realen lückenhaften Arrays unterstützt.
Damit ein Objekt diesen Iterator verwenden kann, fügt man diese Funktion in die Klassendefinition ein:

    _NewEnum()
    {
    	return new CEnumerator(this)
    }

Quelle: http://www.autohotkey.com/board/topic/2667-suggestions-on-documentation-improvements/?p=531509
*/

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

; Test-Klasse, um die Verwendung zu demonstrieren
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 Performance haben.
        ; Das bedeutet aber auch, dass keine Key-Value-Paare beim Iterieren eingefügt werden können, weil der Bereich ansonsten 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 != ""
    }
}