表作为字典 #
一、字典基础 #
1.1 创建字典 #
lua
-- 空字典
local dict = {}
-- 初始化字典
local person = {
name = "张三",
age = 25,
city = "北京"
}
-- 使用方括号初始化
local config = {
["host"] = "localhost",
["port"] = 8080,
["timeout"] = 30
}
1.2 键的类型 #
lua
local dict = {}
-- 字符串键(最常用)
dict.name = "Lua"
-- 数字键
dict[1] = "first"
dict[100] = "hundred"
-- 布尔键
dict[true] = "yes"
dict[false] = "no"
-- 表键
local key_table = {id = 1}
dict[key_table] = "table value"
-- 函数键(不常用)
local key_func = function() end
dict[key_func] = "function value"
-- 注意:nil 不能作为键
-- dict[nil] = "error" -- 错误
1.3 访问字典 #
lua
local person = {name = "张三", age = 25}
-- 点语法(键必须是有效标识符)
print(person.name) -- 张三
-- 方括号语法(任意键)
print(person["name"]) -- 张三
-- 动态键
local key = "age"
print(person[key]) -- 25
二、字典操作 #
2.1 添加和修改 #
lua
local dict = {}
-- 添加
dict.name = "Lua"
dict["version"] = 5.4
-- 修改
dict.name = "Lua 5.4"
-- 批量添加
local function extend(dict, items)
for k, v in pairs(items) do
dict[k] = v
end
end
extend(dict, {
author = "PUC-Rio",
year = 1993
})
2.2 删除 #
lua
local dict = {a = 1, b = 2, c = 3}
-- 设置为 nil
dict.b = nil
-- 检查是否删除
print(dict.b) -- nil
-- 删除函数
local function remove_key(dict, key)
local value = dict[key]
dict[key] = nil
return value
end
2.3 检查键是否存在 #
lua
local dict = {name = "Lua", version = 5.4}
-- 方法1:与 nil 比较
if dict.name ~= nil then
print("name 存在")
end
-- 方法2:直接判断(注意:false 也是有效值)
if dict.name then
print("name 存在且不为 nil/false")
end
-- 方法3:检查值为 false 的情况
local function has_key(dict, key)
return dict[key] ~= nil
end
-- 方法4:使用 rawget(避免 __index)
if rawget(dict, "name") ~= nil then
print("name 存在")
end
三、字典遍历 #
3.1 pairs 遍历 #
lua
local dict = {a = 1, b = 2, c = 3}
-- 基本遍历
for k, v in pairs(dict) do
print(k, v)
end
-- 只遍历键
for k in pairs(dict) do
print(k)
end
-- 只遍历值
for _, v in pairs(dict) do
print(v)
end
3.2 有序遍历 #
lua
-- 按键排序遍历
local function sorted_pairs(t)
local keys = {}
for k in pairs(t) do
table.insert(keys, k)
end
table.sort(keys)
local i = 0
return function()
i = i + 1
local k = keys[i]
if k then
return k, t[k]
end
end
end
local dict = {c = 3, a = 1, b = 2}
for k, v in sorted_pairs(dict) do
print(k, v)
end
-- a 1
-- b 2
-- c 3
3.3 按值排序遍历 #
lua
local function sorted_by_value(t)
local items = {}
for k, v in pairs(t) do
table.insert(items, {key = k, value = v})
end
table.sort(items, function(a, b)
return a.value < b.value
end)
local i = 0
return function()
i = i + 1
local item = items[i]
if item then
return item.key, item.value
end
end
end
local scores = {Alice = 85, Bob = 92, Charlie = 78}
for name, score in sorted_by_value(scores) do
print(name, score)
end
-- Charlie 78
-- Alice 85
-- Bob 92
四、字典方法 #
4.1 获取所有键 #
lua
local function keys(t)
local result = {}
for k in pairs(t) do
table.insert(result, k)
end
return result
end
local dict = {a = 1, b = 2, c = 3}
local ks = keys(dict)
print(table.concat(ks, ", ")) -- a, b, c(顺序不确定)
4.2 获取所有值 #
lua
local function values(t)
local result = {}
for _, v in pairs(t) do
table.insert(result, v)
end
return result
end
local dict = {a = 1, b = 2, c = 3}
local vs = values(dict)
print(table.concat(vs, ", ")) -- 1, 2, 3(顺序不确定)
4.3 计数 #
lua
-- 计算键值对数量
local function count(t)
local n = 0
for _ in pairs(t) do
n = n + 1
end
return n
end
local dict = {a = 1, b = 2, c = 3}
print(count(dict)) -- 3
4.4 判断是否为空 #
lua
local function is_empty(t)
return next(t) == nil
end
print(is_empty({})) -- true
print(is_empty({a=1})) -- false
五、字典合并 #
5.1 合并两个字典 #
lua
local function merge(t1, t2)
local result = {}
for k, v in pairs(t1) do
result[k] = v
end
for k, v in pairs(t2) do
result[k] = v
end
return result
end
local a = {x = 1, y = 2}
local b = {y = 20, z = 3}
local c = merge(a, b)
print(c.x, c.y, c.z) -- 1 20 3
5.2 深度合并 #
lua
local function deep_merge(t1, t2)
local result = {}
for k, v in pairs(t1) do
if type(v) == "table" and type(t2[k]) == "table" then
result[k] = deep_merge(v, t2[k])
else
result[k] = v
end
end
for k, v in pairs(t2) do
if result[k] == nil then
result[k] = v
end
end
return result
end
六、字典应用 #
6.1 计数器 #
lua
local function word_count(text)
local counts = {}
for word in string.gmatch(text:lower(), "%a+") do
counts[word] = (counts[word] or 0) + 1
end
return counts
end
local text = "hello world hello lua world world"
local counts = word_count(text)
for word, count in pairs(counts) do
print(word, count)
end
-- hello 2
-- world 3
-- lua 1
6.2 缓存 #
lua
local function create_cache()
local cache = {}
return {
get = function(key)
return cache[key]
end,
set = function(key, value)
cache[key] = value
end,
has = function(key)
return cache[key] ~= nil
end,
delete = function(key)
cache[key] = nil
end,
clear = function()
cache = {}
end
}
end
local cache = create_cache()
cache.set("user:1", {name = "Alice"})
print(cache.get("user:1").name) -- Alice
6.3 配置管理 #
lua
local Config = {}
Config.defaults = {
host = "localhost",
port = 8080,
debug = false,
timeout = 30
}
function Config.create(overrides)
local config = {}
for k, v in pairs(Config.defaults) do
config[k] = v
end
if overrides then
for k, v in pairs(overrides) do
config[k] = v
end
end
return config
end
local config = Config.create({
port = 3000,
debug = true
})
print(config.host, config.port, config.debug)
-- localhost 3000 true
6.4 对象池 #
lua
local function create_pool(create_fn, reset_fn)
local pool = {}
local available = {}
return {
acquire = function()
if #available > 0 then
return table.remove(available)
end
return create_fn()
end,
release = function(obj)
reset_fn(obj)
table.insert(available, obj)
end,
size = function()
return #available
end
}
end
七、字典与元表 #
7.1 默认值 #
lua
local function dict_with_default(default)
return setmetatable({}, {
__index = function(t, k)
return default
end
})
end
local dict = dict_with_default(0)
dict.a = 1
print(dict.a) -- 1
print(dict.b) -- 0(默认值)
7.2 只读字典 #
lua
local function readonly(t)
local proxy = {}
setmetatable(proxy, {
__index = t,
__newindex = function()
error("字典是只读的", 2)
end
})
return proxy
end
local original = {a = 1, b = 2}
local ro = readonly(original)
print(ro.a) -- 1
-- ro.c = 3 -- 错误:字典是只读的
7.3 弱引用字典 #
lua
-- 弱键字典
local weak_keys = setmetatable({}, {__mode = "k"})
-- 弱值字典
local weak_values = setmetatable({}, {__mode = "v"})
-- 弱键弱值
local weak_both = setmetatable({}, {__mode = "kv"})
八、性能优化 #
8.1 预分配哈希槽 #
lua
-- 预分配(LuaJIT)
-- local dict = table.new(0, 100) -- 0 数组槽,100 哈希槽
-- 普通方式
local dict = {}
for i = 1, 100 do
dict["key" .. i] = i
end
8.2 缓存常用键 #
lua
-- 缓存键字符串
local KEY_NAME = "name"
local KEY_AGE = "age"
local person = {}
person[KEY_NAME] = "张三"
person[KEY_AGE] = 25
九、总结 #
本章介绍了 Lua 表作为字典的使用:
- 字典基础:创建、键类型、访问方式
- 字典操作:添加、修改、删除、检查
- 字典遍历:pairs、有序遍历
- 字典方法:keys、values、count
- 字典合并:浅合并、深合并
- 应用场景:计数器、缓存、配置管理
- 元表应用:默认值、只读、弱引用
下一章,我们将学习模块与包。
最后更新:2026-03-27