Skip to content

table(表)

表(table)是 Lua 中唯一的数据结构,它可以用来表示数组、字典、对象等。本章节将介绍 Lua 中表的定义、访问、修改和相关操作。

表的定义

在 Lua 中,表可以通过 {} 来定义:

lua
-- 空表
local t = {}

-- 包含元素的表
local person = {
  name = "张三",
  age = 30,
  gender = "男"
}

-- 数组形式的表
local fruits = {"苹果", "香蕉", "橙子", "葡萄"}

表的访问

访问表中的元素

lua
local person = {
  name = "张三",
  age = 30,
  gender = "男"
}

-- 使用点号访问
print(person.name)  -- 输出 张三

-- 使用方括号访问
print(person["age"])  -- 输出 30

访问数组元素

lua
local fruits = {"苹果", "香蕉", "橙子", "葡萄"}
print(fruits[1])  -- 输出 苹果
print(fruits[2])  -- 输出 香蕉

表的修改

修改表中的元素

lua
local person = {
  name = "张三",
  age = 30,
  gender = "男"
}

person.age = 31
print(person.age)  -- 输出 31

person["gender"] = "女"
print(person.gender)  -- 输出 女

添加新元素

lua
local person = {
  name = "张三",
  age = 30
}

person.gender = "男"
print(person.gender)  -- 输出 男

person["hobby"] = "读书"
print(person.hobby)  -- 输出 读书

删除元素

lua
local person = {
  name = "张三",
  age = 30,
  gender = "男"
}

person.gender = nil
print(person.gender)  -- 输出 nil

表的遍历

使用 pairs 遍历所有键值对

lua
local person = {
  name = "张三",
  age = 30,
  gender = "男"
}

for key, value in pairs(person) do
  print(key, value)
end

输出:

name	张三
age	30
gender	男

使用 ipairs 遍历数组部分

lua
local fruits = {"苹果", "香蕉", "橙子", "葡萄"}

for i, fruit in ipairs(fruits) do
  print(i, fruit)
end

输出:

1	苹果
2	香蕉
3	橙子
4	葡萄

表的操作

table.insert

在表的指定位置插入元素:

lua
local fruits = {"苹果", "香蕉", "橙子"}
table.insert(fruits, "葡萄")  -- 在末尾插入
print(fruits[4])  -- 输出 葡萄

table.insert(fruits, 2, "草莓")  -- 在索引 2 处插入
print(fruits[2])  -- 输出 草莓
print(fruits[3])  -- 输出 香蕉

table.remove

删除表中指定位置的元素:

lua
local fruits = {"苹果", "香蕉", "橙子", "葡萄"}
table.remove(fruits, 2)  -- 删除索引 2 处的元素
print(fruits[2])  -- 输出 橙子

local last = table.remove(fruits)  -- 删除末尾元素
print(last)  -- 输出 葡萄

table.sort

对表进行排序:

lua
local numbers = {3, 1, 4, 1, 5, 9, 2, 6}
table.sort(numbers)
for i, num in ipairs(numbers) do
  print(num)
end

输出:

1
1
2
3
4
5
6
9

table.concat

拼接表中的元素:

lua
local fruits = {"苹果", "香蕉", "橙子", "葡萄"}
local str = table.concat(fruits, ", ")
print(str)  -- 输出 苹果, 香蕉, 橙子, 葡萄

表的长度

使用 # 运算符获取表的长度:

lua
local fruits = {"苹果", "香蕉", "橙子", "葡萄"}
print(#fruits)  -- 输出 4

local person = {
  name = "张三",
  age = 30,
  gender = "男"
}
print(#person)  -- 输出 0,因为 # 只计算数组部分的长度

嵌套表

表可以嵌套使用,形成多维表:

lua
local matrix = {
  {1, 2, 3},
  {4, 5, 6},
  {7, 8, 9}
}

print(matrix[2][2])  -- 输出 5

for i = 1, #matrix do
  for j = 1, #matrix[i] do
    io.write(matrix[i][j], " ")
  end
  io.write("\n")
end

输出:

1 2 3 
4 5 6 
7 8 9

表的引用

在 Lua 中,表是引用类型,当你将一个表赋值给另一个变量时,它们指向同一个表:

lua
local t1 = {a = 1, b = 2}
local t2 = t1

t2.a = 10
print(t1.a)  -- 输出 10,因为 t1 和 t2 指向同一个表

表的复制

浅复制

lua
function shallowCopy(t)
  local copy = {}
  for k, v in pairs(t) do
    copy[k] = v
  end
  return copy
end

local t1 = {a = 1, b = 2, c = {d = 3}}
local t2 = shallowCopy(t1)

t2.a = 10
t2.c.d = 30

print(t1.a)  -- 输出 1,因为浅复制只复制表的顶层元素
print(t1.c.d)  -- 输出 30,因为嵌套表仍然是引用

深复制

lua
function deepCopy(t)
  if type(t) ~= "table" then
    return t
  end
  local copy = {}
  for k, v in pairs(t) do
    copy[k] = deepCopy(v)
  end
  return copy
end

local t1 = {a = 1, b = 2, c = {d = 3}}
local t2 = deepCopy(t1)

t2.a = 10
t2.c.d = 30

print(t1.a)  -- 输出 1
print(t1.c.d)  -- 输出 3,因为深复制复制了所有嵌套表

表的应用

示例 1:实现栈

lua
local Stack = {}

function Stack:new()
  local obj = {}
  setmetatable(obj, self)
  self.__index = self
  return obj
end

function Stack:push(value)
  table.insert(self, value)
end

function Stack:pop()
  return table.remove(self)
end

function Stack:size()
  return #self
end

-- 使用栈
local stack = Stack:new()
stack:push(1)
stack:push(2)
stack:push(3)
print(stack:pop())  -- 输出 3
print(stack:size())  -- 输出 2

示例 2:实现队列

lua
local Queue = {}

function Queue:new()
  local obj = {}
  setmetatable(obj, self)
  self.__index = self
  return obj
end

function Queue:enqueue(value)
  table.insert(self, value)
end

function Queue:dequeue()
  return table.remove(self, 1)
end

function Queue:size()
  return #self
end

-- 使用队列
local queue = Queue:new()
queue:enqueue(1)
queue:enqueue(2)
queue:enqueue(3)
print(queue:dequeue())  -- 输出 1
print(queue:size())  -- 输出 2

小结

本章节介绍了 Lua 中表的定义、访问、修改、遍历和相关操作,包括表的长度、嵌套表、表的引用和复制等内容。表是 Lua 中最核心的数据结构,掌握这些内容,对于编写 Lua 程序非常重要。