返回首页

教程导航

返回首页

🏷️ 标签(1)

🗂️ 分类(1)

第 7 章 表

第 7 章 表

表是 Lua 唯一的内置复合数据结构。它同时承担数组、字典、集合和对象等职责,是后续模块与面向对象实现的基础。

创建与访问表

local user = {
  name = "Ada",
  age = 30,
  ["is-active"] = true
}

print(user.name)
print(user["age"])

user.email = "ada@example.com"
user["age"] = 31

键可以是数字、字符串、布尔值、表或函数。表键按引用比较:

local key = {}
local data = {}
data[key] = "value"

print(data[key]) -- value
print(data[{}])  -- nil

数组、序列与长度

以连续正整数为键的表通常称为序列:

local languages = { "Lua", "C", "Rust" }

print(languages[1]) -- Lua
print(languages[2]) -- C
print(#languages)   -- 3

Lua 索引从 1 开始,这是新手最容易出错的地方。添加元素可使用 #values + 1:

languages[#languages + 1] = "Go"

如果表中存在空洞,# 的结果没有可靠定义:

local sparse = {}
sparse[1] = "a"
sparse[3] = "c"

-- sparse[2] 为 nil,#sparse 可能返回 1 或 3

需要对稀疏数据计数时,显式维护长度或遍历计数。

字典与嵌套数据

local config = {
  server = {
    host = "127.0.0.1",
    port = 8080
  },
  features = {
    cache = true,
    tracing = false
  }
}

print(config.server.host)
print(config.features.cache)

深层字段可能为 nil,直接连续索引会报错:

local function safeGet(value, path)
  local current = value
  for key in path:gmatch("[^%.]+") do
    if type(current) ~= "table" then
      return nil
    end
    current = current[key]
  end
  return current
end

print(safeGet(config, "server.port"))
print(safeGet(config, "server.timeout.value"))

遍历表

数组使用 ipairs:

for index, value in ipairs(languages) do
  print(index, value)
end

字典使用 pairs:

for key, value in pairs(config.server) do
  print(key, value)
end

遍历顺序不应依赖。需要稳定排序时,先收集键再排序:

local keys = {}
for key in pairs(config.server) do
  keys[#keys + 1] = key
end

table.sort(keys)
for _, key in ipairs(keys) do
  print(key, config.server[key])
end

表操作实战

深拷贝

local function deepCopy(value, seen)
  if type(value) ~= "table" then
    return value
  end

  seen = seen or {}
  if seen[value] then
    return seen[value]
  end

  local copy = {}
  seen[value] = copy

  for key, item in pairs(value) do
    copy[deepCopy(key, seen)] = deepCopy(item, seen)
  end

  return copy
end

seen 用于处理循环引用,避免递归无限展开。

按字段分组

local function groupBy(items, keySelector)
  local groups = {}

  for _, item in ipairs(items) do
    local key = keySelector(item)
    groups[key] = groups[key] or {}
    groups[key][#groups[key] + 1] = item
  end

  return groups
end

移除元素

删除数组元素后可能产生空洞。需要保持连续序列时,可以从后向前遍历:

local values = { 1, 2, 3, 4, 5 }

for index = #values, 1, -1 do
  if values[index] % 2 == 0 then
    table.remove(values, index)
  end
end

上一章:函数 | 下一章:迭代器