For-loop

对对象中的每对键值对重复执行一或多条语句.

For Value1 , Value2 in Expression

参数

Value1, Value2

类型: 变量

用于存储枚举器在每次迭代开始时返回的值的变量. 这些值的性质由枚举器定义, 枚举器由 Expression 决定. 这些变量不能是动态的.

当循环中断或完成时, 这些变量将恢复到原来的值. 如果一个循环变量是 ByRef 参数, 那么目标变量不受循环的影响. 引用该变量(如果是局部变量) 的闭包也不受影响, 并将仍保持为它在循环外的值.

注意: 即使定义在循环主体内, 引用循环变量的嵌套函数也不能看到或改变当前迭代的值. 相反, 要显式传递变量或将其值绑定到一个参数.

如果被枚举器支持, 最多支持 19 个变量.

变量可以被省略. 例如, for , value in myMap 仅用第二个参数调用 myMap 的枚举器, 而省略其第一个参数. 如果枚举器是用户定义的, 并且参数是强制性的, 那么就会像往常一样抛出异常. 如果没有变量或逗号, 传递给 __Enum 的参数数为 0; 否则为 1 加上存在的逗号数.

Expression

类型: 对象

结果为可枚举对象的表达式, 或包含可枚举对象的变量.

备注

可以选择将参数列表括在括号中. 例如: for (val in myarray)

枚举过程如下:

尽管不完全等同于 for 循环, 下面演示了这个过程:

_enum := Expression
try _enum := _enum.__Enum(2)
while _enum(&Value1, &Value2)
{
    ...
}

与上面的代码一样, 如果 Expression 或 __Enum 产生了一个不能被调用的值, 则抛出异常.

在枚举属性, 方法或数组元素时, 插入或删除该类型的项目通常是不安全的. 这样做可能导致某些项目被多次跳过或枚举. 一种解决方法是建立要删除的项目列表, 然后在第一个循环完成后使用第二个循环删除这些项目.

for 循环后通常跟着区块, 这是构成循环 主体 的语句的集合. 不过, 在单语句的循环中可以不使用区块(用于此目的时 "if" 与其相匹配的 "else" 一起被视为单语句). 可以选择使用 One True Brace(OTB) 样式, 这样允许左大括号在同一行而不是在其下面. 例如: for x, y in z {.

和所有的循环一样, 可以使用 Break, ContinueA_Index.

循环后面可以有一个可选的 Else 语句, 如果循环的迭代次数为零, 则执行 Else 语句.

COM 对象

因为 Value1Value2 是直接传递给枚举器的, 所以它们的值取决于被枚举的对象类型. 对于 COM 对象, Value1 包含由 IEnumVARIANT::Next() 返回的值, 而 Value2 包含了表示其变体类型的数字. 例如, 用于 Scripting.Dictionary 对象时, 每个 Value1 包含字典中的键, 而 Value2 通常为 8(对于字符串) 和 3(对于整数). 有关类型代码表, 请参阅 ComObjType.

枚举 SafeArray 时, Value1 包含了当前元素, 而 Value2 包含其变体类型.

Enumerator 对象, OwnProps, While-loop, Loop, Until, Break, Continue, 区块

示例

列出对象的自有属性.

colours := {red: 0xFF0000, blue: 0x0000FF, green: 0x00FF00}
; 上面的表达式可以直接代替下面的 "colours":
s := ""
for k, v in colours.OwnProps()
    s .= k "=" v "`n"
MsgBox s

列出所有打开的资源管理器和 Internet Explorer 窗口, 使用 Shell 对象.

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

将枚举器定义为胖箭头函数. 返回斐波那契数列中的数字, 无限次或直到停止.

for n in FibF()
    if MsgBox("#" A_Index " = " n "`nContinue?",, "y/n") = "No"
        break

FibF() {
    a := 0, b := 1
    return (&n) => (
        n := c := b, b += a, a := c,
        true
    )
}

将枚举器定义为. 与前面的示例相同.

for n in FibC()
    if MsgBox("#" A_Index " = " n "`nContinue?",, "y/n") = "No"
        break

class FibC {
    a := 0, b := 1
    Call(&n) {
        n := c := this.b, this.b += this.a, this.a := c
        return true
    }
}