Skip to content

Lua 数组

在 Lua 中,“数组”的概念通常是使用整数键的表(tables)来实现的。它们是有序的对象集合。数组可以是单维的(列表)或多维的(类似于带有行和列的表格,通常表示为表的表)。

Lua 表在用作数组时没有固定大小。它们可以根据需要动态增长或缩小,仅受可用内存的限制。在 Lua 中,数组的约定是基于 1 的索引,这意味着第一个元素位于索引 1。长度操作符 # 可以用于获取一个序列(从索引 1 开始且没有空隙的数组)的大小。

单维数组是一个简单的、使用数字索引的表。您可以使用循环来初始化和遍历它。按照约定,Lua 数组从索引 1 开始。

local my_array = {"Lua", "Tutorial"}
-- Iterate from 1 up to the length of the array
for i = 1, #my_array do
print(my_array[i])
end
-- Accessing an element at an unassigned index (e.g., 0 or 3 in this case)
print(my_array[0]) -- Lua convention is 1-based indexing
print(my_array[3])

运行上述代码后,输出将是:

Lua
Tutorial
nil
nil

如上所示,访问未赋值的索引(例如,在这个长度为 2 的、基于 1 索引的数组中访问 my_array[0] 或 my_array[3])会得到 nil。虽然 Lua 的约定是基于 1 的索引(并且 # 和 ipairs 等函数依赖于此),但表在技术上可以存储任何整数索引上的值,包括 0 或负数。以下是使用各种索引的示例:

local custom_indexed_array = {}
custom_indexed_array[-1] = "Negative One"
custom_indexed_array[0] = "Zero"
custom_indexed_array[1] = "One"
custom_indexed_array[2] = "Two"
print(custom_indexed_array[-1])
print(custom_indexed_array[0])
print(custom_indexed_array[1])
-- Note: The # operator might not give the expected count for non-sequence tables.
-- For iterating such tables, `pairs` might be more suitable than `ipairs`.

运行上述代码后,输出将是:

Negative One
Zero
One

常见陷阱:对非序列的数组(即元素之间有 nil 值,或不是从索引 1 开始的数组)使用 ipairs 或长度操作符 # 可能会导致意外结果。ipairs 会从 1 开始迭代,直到遇到第一个 nil 整数键。# 操作符对于序列是可靠的。

多维数组在 Lua 中最常见的实现方式是表的表(table of tables)(一个数组,其中每个元素都是另一个数组)。

  • 表的表(最常见和惯用的方法)
  • 使用计算索引的单表(较不常见,用于特定优化场景)

以下是一个使用表的表方法实现的 2x2 多维数组示例:

-- Initialize a 2x2 matrix (table of tables)
local matrix = {}
local num_rows = 2
local num_cols = 2
for i = 1, num_rows do
matrix[i] = {} -- Create a new row (which is a table)
for j = 1, num_cols do
matrix[i][j] = string.format("Row %d, Col %d", i, j)
end
end
-- Access and print elements
for i = 1, num_rows do
for j = 1, num_cols do
print(matrix[i][j])
end
end

运行上述代码后,输出将是:

Row 1, Col 1
Row 1, Col 2
Row 2, Col 1
Row 2, Col 2

另一种替代方法是,在一个表中通过计算索引来管理数据,这对于一般用途来说不如表的表常见,因为管理起来更复杂,但可以在性能关键的场景下用于优化内存布局:

-- Initialize a 2x2 matrix using a single table and calculated indices
local flat_matrix = {}
local num_rows = 2
local num_cols = 2
for r = 1, num_rows do
for c = 1, num_cols do
-- Formula to map (r, c) to a single index
local index = (r - 1) * num_cols + c
flat_matrix[index] = string.format("Val at (%d,%d)", r, c)
end
end
-- Access and print elements
for r = 1, num_rows do
for c = 1, num_cols do
local index = (r - 1) * num_cols + c
print(flat_matrix[index])
end
end

运行上述代码后,输出将是:

Val at (1,1)
Val at (1,2)
Val at (2,1)
Val at (2,2)

Lua 的表本质上是稀疏的(sparse)。如果一个索引没有赋值,它就不会为该“槽位”消耗内存(除了表的整体结构开销)。这在内存效率上可能很高,特别是对于许多元素可能是 nil 或默认值的数组或矩阵。

更多资源:关于表及其用作数组的详细信息,请参阅 Lua 官方文档。