Lua Table(表)

这一个章节是lua比较重要的一个部分,因为lua是唯一的数据结构,它融合和多种功能于一身。大概讲解table的基础操作以及作为数组和字典以及高级特性。

一、什么是Lua Table?

在Lua中,**table(表)**​ 是唯一的数据结构机制,它融合了数组、字典、对象、模块等多种功能于一身。Table不仅是Lua中最强大、最灵活的特性,也是理解Lua编程思想的关键。

复制代码
-- 最简单的table示例
local empty_table = {}  -- 空表
local person = {name = "张三", age = 25}  -- 类似字典的table
local numbers = {1, 2, 3, 4, 5}  -- 类似数组的table

二、Table的创建与基本操作

2.1 创建Table

复制代码
-- 方式1:使用花括号
local t1 = {}

-- 方式2:创建时初始化
local t2 = {
    "apple",  -- 索引为1
    "banana", -- 索引为2
    color = "red",  -- 键为"color"
    count = 10      -- 键为"count"
}

-- 方式3:使用table构造函数
local t3 = table.pack(1, 2, 3)  -- Lua 5.2+

2.2 访问和修改元素

复制代码
local fruits = {"apple", "banana", "orange"}

-- 访问数组部分(整数索引)
print(fruits[1])  -- 输出: apple
print(fruits[2])  -- 输出: banana

-- 修改元素
fruits[3] = "grape"
fruits[4] = "mango"  -- 添加新元素

-- 使用字符串键(字典部分)
local person = {}
person.name = "李四"
person["age"] = 30

-- 混合访问
local mixed = {
    1, 2, 3,
    name = "王五",
    scores = {90, 85, 95}
}
print(mixed.name)       -- 输出: 王五
print(mixed.scores[2])  -- 输出: 85

三、Table作为数组使用

3.1 基本数组操作

复制代码
local array = {"a", "b", "c", "d"}

-- 获取长度(连续数字索引部分)
print(#array)  -- 输出: 4

-- 遍历数组
for i = 1, #array do
    print(i, array[i])
end

-- 使用ipairs迭代器(推荐)
for index, value in ipairs(array) do
    print(index, value)
end

3.2 常用数组函数

复制代码
local nums = {3, 1, 4, 1, 5, 9}

-- 插入元素
table.insert(nums, 2)      -- 在末尾插入
table.insert(nums, 3, 7)   -- 在位置3插入7

-- 删除元素
table.remove(nums, 2)      -- 删除位置2的元素

-- 排序
table.sort(nums)           -- 升序排序
table.sort(nums, function(a, b) return a > b end)  -- 降序排序

-- 连接为字符串
local str = table.concat(nums, ", ")  -- "1, 1, 3, 4, 5, 9"

四、Table作为字典使用

4.1 字典操作

复制代码
local dict = {
    name = "小明",
    age = 20,
    city = "北京"
}

-- 访问
print(dict.name)      -- 输出: 小明
print(dict["age"])    -- 输出: 20

-- 添加/修改
dict.gender = "男"
dict["score"] = 95

-- 删除(赋值为nil)
dict.city = nil

-- 检查键是否存在
if dict.name then
    print("姓名存在: " .. dict.name)
end

-- 更安全的检查
if dict.city ~= nil then
    print("城市存在")
end

4.2 遍历字典

复制代码
local student = {
    name = "小红",
    age = 19,
    major = "计算机科学",
    grade = "大三"
}

-- 使用pairs遍历所有键值对
for key, value in pairs(student) do
    print(key .. ": " .. tostring(value))
end

-- 只遍历数组部分使用ipairs
-- 只遍历字典部分需要自己筛选
for key, value in pairs(student) do
    if type(key) == "string" then  -- 只处理字符串键
        print(key, value)
    end
end

五、Table的高级特性

5.1 嵌套Table

复制代码
local company = {
    name = "科技公司",
    employees = {
        {
            id = 1,
            name = "张三",
            department = "研发部"
        },
        {
            id = 2,
            name = "李四",
            department = "市场部"
        }
    },
    departments = {
        rnd = "研发部",
        sales = "销售部",
        hr = "人力资源部"
    }
}

-- 访问嵌套数据
print(company.employees[1].name)      -- 张三
print(company.departments.rnd)        -- 研发部

5.2 引用语义

复制代码
-- Table是引用类型
local t1 = {x = 10, y = 20}
local t2 = t1  -- t2和t1引用同一个table
t2.x = 100
print(t1.x)  -- 输出: 100

-- 复制table(浅拷贝)
function shallowCopy(original)
    local copy = {}
    for k, v in pairs(original) do
        copy[k] = v
    end
    return copy
end

-- 深拷贝(递归复制)
function deepCopy(original)
    if type(original) ~= "table" then
        return original
    end
    local copy = {}
    for k, v in pairs(original) do
        copy[k] = deepCopy(v)
    end
    return copy
end

5.3 Metatable(元表)

复制代码
-- 创建两个table
local t1 = {10, 20, 30}
local t2 = {40, 50, 60}

-- 创建元表
local mt = {
    -- 定义加法行为
    __add = function(a, b)
        local result = {}
        for i = 1, #a do
            result[i] = a[i] + b[i]
        end
        return result
    end,
    
    -- 定义索引访问行为
    __index = function(table, key)
        if key == "sum" then
            local total = 0
            for i = 1, #table do
                total = total + table[i]
            end
            return total
        end
    end
}

-- 设置元表
setmetatable(t1, mt)
setmetatable(t2, mt)

-- 使用元表特性
local t3 = t1 + t2  -- 调用__add
print(t3[1], t3[2], t3[3])  -- 50, 70, 90

print(t1.sum)  -- 调用__index,输出: 60

六、实用技巧和最佳实践

6.1 作为集合使用

复制代码
-- 使用table实现集合
local set = {
    apple = true,
    banana = true,
    orange = true
}

-- 添加元素
set.grape = true

-- 检查元素是否存在
if set.apple then
    print("集合中有苹果")
end

-- 删除元素
set.banana = nil

6.2 作为模块使用

复制代码
-- 创建模块
local mymodule = {}

-- 私有变量(不导出)
local privateVar = "私有数据"

-- 公有函数
function mymodule.hello(name)
    return "你好, " .. name
end

function mymodule.add(a, b)
    return a + b
end

-- 返回模块
return mymodule

6.3 配置管理

复制代码
-- 游戏配置
local config = {
    graphics = {
        resolution = {1920, 1080},
        fullscreen = true,
        shadows = "high"
    },
    audio = {
        volume = 0.8,
        enableMusic = true,
        enableSFX = true
    },
    gameplay = {
        difficulty = "normal",
        language = "zh_CN"
    }
}

-- 访问配置
if config.graphics.fullscreen then
    -- 设置为全屏模式
end

七、性能注意事项

  1. 预分配数组大小(当大小已知时):

    local largeArray = {}
    for i = 1, 10000 do
    largeArray[i] = i -- 动态增长,可能触发多次重哈希
    end

    -- 更好的方式
    local largeArray = table.create(10000) -- Lua 5.4+
    for i = 1, 10000 do
    largeArray[i] = i
    end

  2. 避免在循环中创建table

    -- 不好
    for i = 1, 1000 do
    local temp = {x = i, y = i*2} -- 每次循环创建新table
    -- 使用temp...
    end

    -- 更好
    local temp = {}
    for i = 1, 1000 do
    temp.x = i
    temp.y = i * 2
    -- 使用temp...
    -- 然后清空或重用
    end

八、总结

Lua table是一个极其灵活和强大的数据结构,它的多功能性体现在:

  1. 数组功能:通过整数索引连续存储数据

  2. 字典功能:通过任意类型的键存储键值对

  3. 对象功能:通过table和元表实现面向对象编程

  4. 模块系统:组织代码和实现命名空间

  5. 配置管理:结构化存储应用程序设置

掌握table是精通Lua的关键。记住以下要点:

  • Table是Lua中唯一的数据结构

  • 同时支持数组和字典两种访问方式

  • 使用ipairs遍历数组部分,pairs遍历所有元素

  • 理解引用语义和复制机制

  • 善用元表实现高级功能。

相关推荐
Davina_yu38 分钟前
Windows 下升级 R 语言至最新版
开发语言·windows·r语言
阿珊和她的猫41 分钟前
IIFE:JavaScript 中的立即调用函数表达式
开发语言·javascript·状态模式
listhi5201 小时前
卷积码编码和维特比译码的MATLAB仿真程序
开发语言·matlab
yuan199971 小时前
基于主成分分析(PCA)的故障诊断MATLAB仿真
开发语言·matlab
J_liaty1 小时前
Java版本演进:从JDK 8到JDK 21的特性革命与对比分析
java·开发语言·jdk
翔云 OCR API1 小时前
发票查验接口详细接收参数说明-C#语言集成完整示例-API高效财税管理方案
开发语言·c#
Chasing Aurora2 小时前
Python后端开发之旅(三)
开发语言·python·langchain·protobuf
kong79069282 小时前
Java基础-Lambda表达式、Java链式编程
java·开发语言·lambda表达式
lixzest3 小时前
C++上位机软件开发入门深度学习
开发语言·c++·深度学习
于越海3 小时前
材料电子理论核心四个基本模型的python编程学习
开发语言·笔记·python·学习·学习方法