这一个章节是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
七、性能注意事项
-
预分配数组大小(当大小已知时):
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 -
避免在循环中创建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是一个极其灵活和强大的数据结构,它的多功能性体现在:
-
数组功能:通过整数索引连续存储数据
-
字典功能:通过任意类型的键存储键值对
-
对象功能:通过table和元表实现面向对象编程
-
模块系统:组织代码和实现命名空间
-
配置管理:结构化存储应用程序设置
掌握table是精通Lua的关键。记住以下要点:
-
Table是Lua中唯一的数据结构
-
同时支持数组和字典两种访问方式
-
使用
ipairs遍历数组部分,pairs遍历所有元素 -
理解引用语义和复制机制
-
善用元表实现高级功能。