# 数组

在 AutoHotkey 中, 有两种不同类型的事物与数组相关:

- 基于对象的数组
- 伪数组(不推荐使用)

注意: 下面的代码示例显示了导致相同最终结果的不同方法.

## 基于对象的数组[AHK_L 31+]

这样的数组可以是关联数组或简单数组. 关联数组使用对象函数或大括号语法创建, 而简单数组使用数组函数或方括号语法创建. 有关更多信息, 请参阅初学者向导(快速入门) 或对象.

以下示例展示了一个简单数组的用法:

    ; 创建数组后, 初始为空:
    Array := [] ; 或 Array := Array()

    ; 写入数据到数组:
    Loop, Read, %A_WinDir%\system.ini ; 此循环获取文件中的每行, 一次一行.
    {
        Array.Insert(A_LoopReadLine) ; 添加此行到数组中.
    }

    ; 从数组中读取:
    ; Loop % Array.MaxIndex()   ; 较传统的方式.
    for index, element in Array ; 在大多数情况下建议使用枚举的方式.
    {
        ; 使用 "Loop", 索引必须是连续的数字, 从 1 到
        ; 数组中元素的个数(或者必须在循环中进行计算).
        ; MsgBox % "Element number " . A_Index . " is " . Array[A_Index]

        ; 使用 "for", 同时提供了索引(或 "键") 及与它关联
        ; 的值, 并且索引可以是您选择的*任何*值.
        MsgBox % "Element number " . index . " is " . element
    }

此例仅演示了对象提供的功能的一个小子集. 可以设置, 获取, 插入, 移除和枚举项目. 除了数字, 还可以把字符串和对象作为键使用. 对象可以作为值存储到其他对象中并且可以作为函数参数或返回值传递. 对象还可以用新功能进行扩展.

尽管 Push() 和枚举器有它们的用途, 不过一些用户可能会发现使用更传统的方法更容易(注释掉的行对应使用下面描述伪数组):

      ; 每个数组在使用前必须进行初始化:
      Array := []

    ; Array%j% := A_LoopField
      Array[j] := A_LoopField

    ; Array%j%_%k% := A_LoopReadLine
      Array[j, k] := A_LoopReadLine

      ArrayCount := 0
      Loop, Read, %A_WinDir%\system.ini
      {
          ArrayCount += 1
        ; Array%ArrayCount% := A_LoopReadLine
          Array[ArrayCount] := A_LoopReadLine
      }

      Loop % ArrayCount
      {
        ; element := Array%A_Index%
          element := Array[A_Index]
        ; MsgBox % "Element number " . A_Index . " is " . Array%A_Index%
          MsgBox % "Element number " . A_Index . " is " . Array[A_Index]
      }

为了方便而使用 ArrayCount 变量保存数组元素个数, 但可以通过 `Array.Count := n` 保存到数组自身中, 或使用 `Array.MaxIndex()` 代替它. 如果希望使用 1 之外的其他值作为起始索引, 还可以使用 `Array.MinIndex()`.

## 伪数组

注意: 如果可能, 请始终使用上面提到的基于对象的数组. 它在几乎每个方面都优于伪数组: 它具有节省空间, 更灵活, 更清晰, 与许多其他编程语言相似的特点.

伪数组主要是概念上的: 每个数组实际上只是一系列连续编号的变量或函数的集合, 它们每个被视为数组的 元素. AutoHotkey 不会以任何方式把这些元素链接在一起.

除了如 StringSplit 和 WinGet List 这样的数组创建命令外, 任何接受 OutputVar 或把值赋给变量的命令都可以用来创建数组. 最简单的例子是赋值运算符 (:=), 如下所示:

    Array%j% := A_LoopField

通过在索引间使用您选择的分隔符可以创建多维数组. 例如:

    Array%j%_%k% := A_LoopReadLine

下面的例子演示了如何创建和访问数组, 这里是从文本文件获取一系列的名称:

    ; 写入到数组:
    ArrayCount := 0
    Loop, Read, %A_WinDir%\system.ini   ; 此循环获取文件中的每行, 一次一行.
    {
        ArrayCount += 1  ; 记录数组中的项目数.
        Array%ArrayCount% := A_LoopReadLine  ; 把此行保存到数组中的下一个元素.
    }

    ; 从数组中读取:
    Loop %ArrayCount%
    {
        ; 下一行使用 := 运算符获取数组元素:
        element := Array%A_Index%  ; A_Index 是内置变量.
        ; 可选地, 您可以使用 "% " 前缀让 MsgBox 或其他一些命令的参数中可以使用表达式:
        MsgBox % "Element number " . A_Index . " is " . Array%A_Index%
    }

一个和数组有关的概念是使用 NumPut() 和 NumGet() 储存/获取一批二进制格式的数字. 这在对性能和/或内存占用有要求时比较有用.

dftg