On this page

Lua table(表)

Lua Table(表)全面指南

Table 是 Lua 中唯一的数据结构,它融合了数组、字典、对象等多种功能于一体。

1. 基本特性

  • 多功能性:可作为数组、字典、集合、对象等使用
  • 灵活性:键和值可以是任意类型(nil 除外)
  • 动态大小:自动扩容和收缩
  • 引用类型:赋值和传参传递的是引用

2. 创建表

空表

local t = {}

带初始值的表

-- 数组式(自动数字索引从1开始)
local arr = {"a", "b", "c"}

-- 字典式
local dict = {
    name = "Lua",
    version = 5.4,
    ["release date"] = "2020"  -- 特殊键名
}

-- 混合式
local mix = {
    "value1",  -- 自动索引1
    "value2",  -- 自动索引2
    key3 = "value3",
    [5] = "value5"  -- 显式数字键
}

3. 访问表元素

点语法(适用于字符串键)

print(dict.name)  -- 输出: Lua
dict.version = 5.3  -- 修改值

方括号语法(通用)

print(arr[1])          -- 输出: a
print(dict["name"])    -- 输出: Lua
mix[5] = "new value"   -- 修改值

使用变量作为键

local key = "version"
print(dict[key])  -- 输出: 5.4

4. 表操作函数

插入元素

table.insert(arr, "d")      -- 末尾插入
table.insert(arr, 2, "x")  -- 在位置2插入

删除元素

table.remove(arr)      -- 删除最后一个
table.remove(arr, 2)   -- 删除位置2的元素

排序

local nums = {3, 1, 4, 1, 5, 9}
table.sort(nums)  -- 升序
table.sort(nums, function(a, b) return a > b end)  -- 降序

拼接

print(table.concat(arr, ", "))  -- 输出: a, x, b, c, d

5. 表遍历

pairs 遍历所有元素

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

ipairs 遍历数组部分

for i, v in ipairs(arr) do
    print(i, v)
end

数值 for 遍历数组

for i = 1, #arr do
    print(arr[i])
end

6. 元表(Metatable)高级功能

元表可以定义表的特殊行为:

local t1 = {1, 2}
local t2 = {3, 4}

-- 创建元表
local mt = {
    __add = function(a, b)  -- 重载+操作符
        local res = {}
        for i = 1, #a do res[i] = a[i] + b[i] end
        return res
    end
}

setmetatable(t1, mt)
setmetatable(t2, mt)

local t3 = t1 + t2  -- 调用__add
print(table.concat(t3, ", "))  -- 输出: 4, 6

常用元方法:

  • __index:访问不存在的键时触发
  • __newindex:给不存在的键赋值时触发
  • __call:把表当函数调用时触发
  • __tostring:定义表的字符串表示

7. 表作为数据结构

实现栈

local stack = {}

function stack.push(item)
    table.insert(stack, item)
end

function stack.pop()
    return table.remove(stack)
end

实现队列

local queue = {}

function queue.enqueue(item)
    table.insert(queue, item)
end

function queue.dequeue()
    return table.remove(queue, 1)
end

实现集合

local set = {}

function set.add(s, item)
    s[item] = true
end

function set.contains(s, item)
    return s[item] == true
end

8. 性能优化技巧

  1. 预分配大数组

    local big = {}
    for i = 1, 10000 do big[i] = true end
    
  2. 避免在数组中间插入/删除(使用链表结构如果需要)

  3. 使用弱表(weak table)管理缓存:

    local cache = setmetatable({}, {__mode = "v"})  -- 值弱引用
    
  4. 复用表对象代替频繁创建新表

9. 特殊用法

环境表 _G

_G.myGlobal = "value"  -- 等同于 myGlobal = "value"

模块模式

local M = {}  -- 模块表

function M.func()
    -- 模块功能
end

return M

面向对象编程

local Person = {}

function Person:new(name)
    local obj = {name = name}
    setmetatable(obj, {__index = Person})
    return obj
end

function Person:greet()
    print("Hello, I'm " .. self.name)
end

local p = Person:new("Alice")
p:greet()  -- 输出: Hello, I'm Alice

Table 是 Lua 的核心,几乎所有的 Lua 特性都是基于表实现的。掌握表的使用是成为 Lua 高手的关键!