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
深拷贝看 Penlight 的 tablex.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。
→ 下一篇 函数