嵌套表和结构化数据
构建嵌套结构并访问深层字段。
嵌套表和结构化数据 是 CoddyKit 上的免费 Lua Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Lua Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Lua Academy 课程共包含 4 节课。
嵌套表基础
表可以将其他表作为值,从而创建任意深度的结构。可以通过连续使用点号或方括号访问嵌套字段。中间缺少表会导致错误——访问深层字段前,请始终确保父表存在。
local company = {
name = "CoddyKit",
address = {
city = "Istanbul",
country = "Turkey",
zip = "34000"
},
employees = 25
}
print(company.name) -- CoddyKit
print(company.address.city) -- Istanbul
print(company["address"]["zip"]) -- 34000安全访问深层字段
在 nil 值上访问字段会因“尝试索引 nil 值”而崩溃。可以使用 and 的短路特性进行保护:t and t.a and t.a.b。有些代码库会定义 get(t, ...) 辅助函数,以安全地遍历一串键。
local function get(t, ...)
local cur = t
for _, key in ipairs({...}) do
if type(cur) ~= "table" then return nil end
cur = cur[key]
end
return cur
end
local data = {user = {profile = {age = 30}}}
print(get(data, "user", "profile", "age")) -- 30
print(get(data, "user", "missing", "field")) -- nil记录数组
一种常见模式是由表(记录)组成的数组。每个元素都是一个带有命名字段的表。使用 ipairs 遍历,并按名称访问字段。这相当于 Lua 中的对象数组或结构体列表。
local users = {
{id=1, name="Alice", score=95},
{id=2, name="Bob", score=87},
{id=3, name="Carol", score=91},
}
for _, user in ipairs(users) do
print(user.id, user.name, user.score)
end动态构建嵌套表
通过按需创建内部表,可以逐步构建嵌套结构。在向表中插入内容前,请始终先初始化该表。一个常见错误是忘记先创建内部表,随后却尝试索引 nil。
local tree = {}
tree.root = {value = 10}
tree.root.left = {value = 5}
tree.root.right = {value = 15}
tree.root.left.left = {value = 2}
print(tree.root.value) -- 10
print(tree.root.left.value) -- 5
print(tree.root.left.left.value) -- 2将表用作类似 JSON 的配置
Lua 表经常用于配置文件,类似于 JSON 或 YAML。该文件返回一个表,应用程序使用 dofile() 或 require() 加载它。嵌套表表示嵌套的配置部分。
-- config.lua (returned table)
local config = {
server = {
host = "0.0.0.0",
port = 8080,
ssl = false,
},
db = {
host = "localhost",
name = "appdb",
pool_size = 10,
},
logging = { level = "info", file = "/var/log/app.log" }
}
print(config.server.port) -- 8080
print(config.db.pool_size) -- 10用邻接表表示图
可以将图表示为由表组成的表:每个键是一个节点,其值是邻居节点列表。对于稀疏图,这种邻接表表示方式节省内存,也便于在 Lua 中使用。
local graph = {
A = {"B", "C"},
B = {"A", "D"},
C = {"A", "D"},
D = {"B", "C"},
}
-- BFS from A
local visited = {A=true}
local queue = {"A"}
while #queue > 0 do
local node = table.remove(queue, 1)
io.write(node .. " ")
for _, neighbor in ipairs(graph[node]) do
if not visited[neighbor] then
visited[neighbor] = true
queue[#queue+1] = neighbor
end
end
end
print() -- A B C D修改嵌套字段
访问父表并为相应的键赋值,即可修改嵌套字段。由于表是按引用传递的,任何接收表的函数都可以直接修改其内容——调用者可以看到这些更改。
local player = {name="Hero", stats={hp=100, mp=50, atk=20}}
local function takeDamage(p, dmg)
p.stats.hp = math.max(0, p.stats.hp - dmg)
end
takeDamage(player, 35)
print(player.stats.hp) -- 65
player.stats.atk = player.stats.atk + 5
print(player.stats.atk) -- 25序列化嵌套表
将嵌套表转换为字符串有助于调试或记录日志。简单的递归序列化器可以处理任意深度,但无法处理循环(循环引用)。
local function serialize(val, indent)
indent = indent or 0
local pad = string.rep(" ", indent)
if type(val) ~= "table" then
return tostring(val)
end
local parts = {"{"}
for k, v in pairs(val) do
parts[#parts+1] = pad.." "..tostring(k).."="..serialize(v,indent+1)
end
parts[#parts+1] = pad.."}"
return table.concat(parts, "\n")
end
local data = {x=1, nested={y=2, z=3}}
print(serialize(data))稀疏矩阵
以朴素方式存储二维矩阵时,大型稀疏输入会浪费内存。请在嵌套表中只存储非零条目:matrix[row][col] = value。当大多数值为零时,这种方式可以高效地表示超大矩阵。
local function newMatrix()
return setmetatable({}, {__index=function(t,k)
local row = {}
rawset(t, k, row)
return row
end})
end
local m = newMatrix()
m[1][1] = 5
m[3][7] = 12
m[100][200] = 99
print(m[1][1]) -- 5
print(m[3][7]) -- 12
print(m[2][5]) -- nil (sparse: no value)深度相等检查
表使用 == 按引用进行比较,而不是按值比较。若要结构化地比较嵌套表,请编写递归相等函数,比较每个键值对,并递归处理嵌套表。
local function deepEqual(a, b)
if type(a) ~= type(b) then return false end
if type(a) ~= "table" then return a == b end
for k, v in pairs(a) do
if not deepEqual(v, b[k]) then return false end
end
for k in pairs(b) do
if a[k] == nil then return false end
end
return true
end
print(deepEqual({1,{2,3}},{1,{2,3}})) -- true
print(deepEqual({1,{2,3}},{1,{2,4}})) -- false快速检查
当访问 t.a.b 且 t.a 为 nil 时会发生什么?
回顾:嵌套表
总结:
- 表可以任意嵌套:
t.a.b.c - 保护深层访问:
t and t.a and t.a.b - 表是引用类型——函数会直接修改表的内容
- 记录数组:
{{name=...},{name=...}} - 稀疏矩阵:使用嵌套表提高内存效率
- 深度相等比较需要递归处理
用 AI 导师学习 Lua — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 40
- 课程
- 159
常见问题解答
「嵌套表和结构化数据」课时是免费的吗?
是的 — 「嵌套表和结构化数据」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Lua Academy 课程的其余内容,请升级到 CoddyKit PRO。 Lua Academy 课程共包含 4 节课。
「嵌套表和结构化数据」这节课中我会学到什么?
构建嵌套结构并访问深层字段。 你通过在浏览器中直接运行的动手代码来练习 Lua Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Lua Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Lua Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「嵌套表和结构化数据」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Lua Academy 课中编写并运行代码吗?
能。每节 Lua Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 将表用作数组
- 将表用作字典
- 使用 pairs 和 ipairs 遍历表
- 嵌套表和结构化数据