Table 是什么

Lua 唯一的复合数据结构。任何 key → 任何 value 的映射:

local t = {}
t[1] = "a"          -- 整数 key
t["name"] = "Alice" -- 字符串 key
t[true] = "yes"     -- 布尔 key
t[print] = "fn"     -- 函数 key

数组、字典、对象、命名空间、模块——全是它。

三种构造语法

local arr  = {10, 20, 30}                       -- 数组式
local dict = {name = "Alice", age = 30}         -- 字典式(key 不带引号)
local mix  = {10, 20, name = "Alice", [99] = "x"}

-- key 不是合法标识符 → 用 [ ]
local t = {["my-key"] = 1, [99] = 2}

-- 完全等价于
local dict2 = {}
dict2.name = "Alice"
dict2.age = 30

字段访问:

print(dict.name)        -- "Alice"
print(dict["name"])     -- 同上

.name["name"] 等价——前者要求 key 是合法标识符。

索引从 1 开始

local arr = {"a", "b", "c"}
print(arr[1])       -- "a"
print(arr[3])       -- "c"
print(arr[0])       -- nil(没东西)
print(arr[4])       -- nil
print(#arr)         -- 3

接受这个事实。所有 Lua 库都按 1-based 设计。

ipairs vs pairs

local t = {"a", "b", "c", name = "Alice"}

for i, v in ipairs(t) do print(i, v) end
-- 1 a / 2 b / 3 c  (只遍历整数 1..n,遇 nil 停)

for k, v in pairs(t) do print(k, v) end
-- 1 a / 2 b / 3 c / name Alice(所有键,无序)
顺序 范围
ipairs 1, 2, 3...(保证升序) 整数键,碰 nil 停
pairs 无保证 所有键

长度运算符 #

#{"a", "b", "c"}        -- 3
#{}                     -- 0

只对数组部分有意义。如果数组有空洞,# 行为未定义:

local t = {1, 2, nil, 4}
print(#t)     -- 可能是 2 或 4,看实现

要严格知数组长度,自己存 t.n 或用 select("#", ...)

数组操作

local arr = {1, 2, 3}
table.insert(arr, 4)        -- {1, 2, 3, 4}
table.insert(arr, 1, 0)     -- {0, 1, 2, 3, 4}(位置 1 插入)
table.remove(arr)           -- 删末尾 → 返回 4
table.remove(arr, 1)        -- 删开头 → 返回 0
table.concat(arr, ", ")     -- "1, 2, 3"
table.sort(arr)             -- 原地排序
table.sort(arr, function(a, b) return a > b end)   -- 自定义比较

字典操作

local d = {a = 1, b = 2}
d.c = 3                 -- 加
d.a = nil               -- 删(设为 nil 等于删除)

for k, v in pairs(d) do print(k, v) end

-- 检查存在
if d.a ~= nil then ... end
-- 或
if d.a then ... end     -- 注意 false 值会被当不存在!

表是引用类型

local a = {1, 2, 3}
local b = a
b[1] = 99
print(a[1])     -- 99(同一个表)

要复制:

local function shallow_copy(t)
    local copy = {}
    for k, v in pairs(t) do copy[k] = v end
    return copy
end

深拷贝看 Penlighttablex.deepcopy

常用模式

作为 set

local seen = {}
seen.alice = true
if seen.alice then print("已见过") end

作为 namespace / 模块

local M = {}
function M.add(a, b) return a + b end
function M.sub(a, b) return a - b end
return M

作为对象:见 第 10 篇 OOP

→ 下一篇 函数