在 Lua 中,table 的键几乎可以是任何类型,但有几个重要的规则和最佳实践需要了解。
1. 主要键类型
(1) 字符串 (string)
这是最常见、最推荐的键类型。
local person = {
name = "Alice", -- 等同于 ["name"] = "Alice"
["age"] = 30 -- 当键名复杂时,必须用方括号
}
(2) 数字 (number)
数字键通常用于实现 "数组"。Lua 数组默认从索引 1
开始。
local fruits = {"apple", "banana"} -- fruits[1], fruits[2]
fruits[100] = "orange" -- 也可以使用任意数字作为键
⚠️ 注意 :数字 0
也是一个有效的键,但它不属于默认的数组部分。
(3) 布尔值 (boolean)
布尔值 true
和 false
也可以作为键。
local settings = {
[true] = "开启状态",
[false] = "关闭状态"
}
(4) 表 (table) / 函数 (function) / 用户数据 (userdata)
这些都是 "引用类型",只有当它们是同一个对象时,才会被视为同一个键。
local t1 = {}
local t2 = {}
local t3 = t1
local cache = {
[t1] = "这是t1",
[function() end] = "这是一个匿名函数"
}
print(cache[t3]) -- 输出 "这是t1",因为 t3 和 t1 是同一个表
print(cache[t2]) -- 输出 nil,因为 t2 是另一个不同的表
2. 两个关键规则
-
nil
键是无效的将
nil
赋值给一个键会删除该键值对。local t = {key = "value"} t.key = nil -- t 现在变成了空表 {}
-
数字
0
和字符串"0"
是不同的键Lua 会区分键的类型。
local t = {[0] = "数字0", ["0"] = "字符串0"} print(t[0]) -- 输出 "数字0" print(t["0"]) -- 输出 "字符串0"
3. 遍历与键类型
不同的遍历方式会处理不同类型的键:
ipairs
: 只遍历连续的、从 1 开始的数字键。pairs
: 遍历所有类型 的键(除了nil
)。
总结与建议
键类型 | 描述 | 推荐场景 |
---|---|---|
字符串 | 最常用,可读性好,性能稳定 | 首选。用于表示配置、对象属性等。 |
数字 | 用于实现数组和有序列表 | 需要按顺序访问一组数据时使用。 |
布尔值 | 只有两个可能的值 | 适用于简单的二态配置。 |
引用类型 | (表 / 函数等)用作临时缓存的键 | 高级用法,如实现备忘录模式或对象唯一标识。 |
在 Lua 中初始化 table 主要有以下几种方式,从简单到复杂排列:
- 创建空表
最基础的方式,创建一个没有任何元素的 table。
local t = {}
- 列表式初始化
用于创建数组或线性表,索引会自动从 1 开始递增。
local fruits = {"apple", "banana", "orange"}
-- fruits[1] = "apple", fruits[2] = "banana"
- 键值对式初始化
用于创建字典或映射,可以自定义任何类型的键(通常是字符串)。
local person = {
name = "Alice",
age = 30,
isStudent = false
}
-- 等同于 person["name"] = person.name = "Alice"
- 混合初始化
在一个 table 中同时包含列表部分和键值对部分。
local data = {
-- 列表部分
"Lua", "Python", "JavaScript",
-- 键值对部分
creator = "Guido van Rossum", -- 注意:这里是个小陷阱!
rating = 9.5
}
⚠️ 重要陷阱:在混合初始化中,所有列表项的自动索引会在所有键值对之前被分配。上面的例子中,data[1] = "Lua", data[2] = "Python", data[3] = "JavaScript"。
- 计算式初始化
在初始化时,用方括号 [] 来包裹表达式,动态计算键名。这对于使用非字符串作为键或动态生成键名非常有用。
local key_name = "score"
local config = {
["player-id"] = 12345, -- 使用特殊字符的字符串键
[key_name] = 90, -- 使用变量作为键
[os.time()] = "start" -- 使用函数调用结果作为键
}
- 构造函数式初始化
通过在 table 构造器中调用函数,可以在创建 table 的同时执行复杂的初始化逻辑。
local function build_user(id)
return {
id = id,
token = "token_" .. id
}
end
local user = build_user(101)
-- user = { id = 101, token = "token_101" }
这些初始化方式是 Lua 中非常基础且重要的知识点。