Table 是 Lua 唯一的結構化數據類型,同時扮演「數組」(整數鍵 1..n)與「字典/哈希表」(任意鍵)角色。本文系統講解 Table 創建、引用語義、標準庫操作函數(insert/remove/concat/sort)、元表機制、弱引用表、性能優化。
nil/NaN 外任意值可作鍵。a = {}; b = a 指向同一底層結構,a = nil 不釋放內存,需無引用才被 GC 回收。-- 字面量
local t1 = { "apple", "banana", "cherry" } -- 陣列風格,鍵 1,2,3
local t2 = { name = "Bob", age = 30, [true] = 1 } -- 字典風格
-- 訪問
print(t1[1]) -- apple
print(t2.name) -- Bob (語法糖)
print(t2["name"]) -- Bob
-- 動態增刪
t2.city = "Taipei"
t2.age = nil -- 刪除鍵
t1[4] = "date" -- 陣列擴展
| 函數 | 用途 | 示例 |
|---|---|---|
table.insert(t, [pos,] val) | 插入元素,pos 預設尾部 | table.insert(t, 2, "new") |
table.remove(t, [pos]) | 移除並返回元素,pos 預設尾部 | table.remove(t, 1) |
table.concat(t, [sep, [i, j]]) | 陣列部分拼接字符串 | table.concat(t, ", ", 2, 3) |
table.sort(t, [comp]) | 原地排序陣列部分 | table.sort(t, function(a,b) return a>b end) |
table.move(a1, f, e, t, a2) | 區間複製(Lua 5.3+) | table.move(src, 1, 3, 1, dst) |
table.pack(...) | 可變參打包為 {n=..., ...} | local args = table.pack(...) |
table.unpack(t, [i, j]) | 陣列解包(Lua 5.2+) | print(table.unpack(t)) |
-- 僅遍歷陣列部分(按順序)
for i = 1, #t do print(i, t[i]) end
-- 遍歷所有鍵值(順序不定)
for k, v in pairs(t) do print(k, v) end
-- 遍歷陣列部分(Lua 5.2+ 推薦)
for i, v in ipairs(t) do print(i, v) end
元表賦予 Table 行為擴展:
local mt = {
__index = function(t, k) return "default_" .. k end, -- 缺失鍵回退
__newindex = function(t, k, v) rawset(t, k, v*2) end, -- 賦值攔截
__add = function(a, b) return setmetatable({a[1]+b[1]}, mt) end, -- 運算符重載
__tostring = function(t) return "MyTable[" .. table.concat(t, ",") .. "]" end
}
local t = setmetatable({10, 20}, mt)
print(t[3]) -- default_3
t[4] = 5 -- 實際存 10
print(t + t) -- MyTable[20,40]
-- 鍵弱引用:鍵無強引用時自動移除條目
local cache = setmetatable({}, { __mode = "k" })
local key = {}
cache[key] = "data"
key = nil
collectgarbage() -- cache 現為空
-- 值弱引用:__mode = "v"
-- 鍵值均弱:__mode = "kv"
local t = {}; for i=1,1e6 do t[i]=0 end 避免多次重哈希。local tinsert = table.insert。next 原生迭代器:for k,v in next, t do ... end 比 pairs 略快。Table 是 Lua 的「瑞士軍刀」。理解其 雙重存儲結構(數組+雜湊)、引用語義、元表擴展、弱引用機制,能寫出既簡潔又高效的代碼。標準庫 table.* 函數覆蓋 90% 操作需求,元表解決剩下 10% 的定制化行為。