Lua 表
Lua - 表
Section titled “Lua - 表”表(Tables)是 Lua 中唯一的数据结构机制,它们是语言的基础。表是一种高度灵活的关联数组(associative array)。这意味着它不仅可以用数字作为索引,还可以使用其他 Lua 值作为索引,例如字符串(strings)、布尔值(booleans),甚至其他表(tables)(除了 nil)。表用于表示普通数组(ordinary arrays)、列表(lists)、符号表(symbol tables)(字典/映射 - dictionaries/maps)、对象(objects)、包(packages)等。
Lua 中的表是动态的;它们的大小不固定,可以根据需要增长或缩小。它们常被称为对象,但理解它们与引用它们的变量是不同的很重要。
创建和使用表
Section titled “创建和使用表”空表使用构造器表达式 {} 创建。
-- Create an empty tablelocal my_table = {}
-- Assign values using keys (indices)my_table[1] = "Apple" -- Numeric key (array-like)my_table["color"] = "Red" -- String key (dictionary-like)my_table[true] = "Is a fruit" -- Boolean key
-- Access values using keysprint(my_table[1]) -- Output: Appleprint(my_table["color"]) -- Output: Red
-- Alternative syntax for string keys (if valid identifiers)my_table.shape = "Round"print(my_table.shape) -- Output: Round
-- Initialize a table with elementslocal another_table = { name = "Banana", color = "Yellow", peel_status = "Peeled", 10, -- equivalent to [1] = 10 20 -- equivalent to [2] = 20}print(another_table.name) -- Output: Bananaprint(another_table[1]) -- Output: 10表的引用和垃圾回收
Section titled “表的引用和垃圾回收”Lua 中的变量本身不存储表,而是存储对表的引用。当你将一个表变量赋值给另一个变量时,两个变量引用内存中的同一个表。通过一个变量修改表会影响到另一个变量。
local t1 = { value = 10 }local t2 = t1 -- t2 now refers to the same table as t1
t2.value = 20print(t1.value) -- Output: 20 (since t1 and t2 point to the same table)
t1 = nil -- t1 no longer refers to the table-- The table itself still exists because t2 refers to it.print(t2.value) -- Output: 20
t2 = nil -- Now, no variable refers to the table.-- Lua's garbage collector will eventually reclaim the memory used by the table.示例:演示表的类型和引用
-- Simple empty tablelocal mytable = {}print("Type of mytable is: " .. type(mytable)) -- Type of mytable is: table
mytable[1] = "Lua"mytable["feature"] = "Tables"print("mytable[1] is: " .. mytable[1]) -- mytable[1] is: Luaprint("mytable.feature is: " .. mytable.feature) -- mytable.feature is: Tables
-- alternatetable and mytable refer to the same tablelocal alternatetable = mytable
print("alternatetable[1] is: " .. alternatetable[1]) -- alternatetable[1] is: Luaalternatetable.feature = "Powerful Tables"print("mytable.feature is now: " .. mytable.feature) -- mytable.feature is now: Powerful Tables
-- Release reference from alternatetablealternatetable = nilprint("alternatetable is: " .. tostring(alternatetable)) -- alternatetable is: nil
-- mytable is still accessibleprint("mytable.feature is still: " .. mytable.feature) -- mytable.feature is still: Powerful Tables
mytable = nil -- Now the table is eligible for garbage collectionprint("mytable is: " .. tostring(mytable)) -- mytable is: nilLua 提供了一个 table 库,其中包含用于操作表的函数,特别是当表被用作数组/列表时。
| 函数签名 | 用途 |
|---|---|
table.concat(list [, sep [, i [, j]]]) | 将 list (一个类数组表) 中从索引 i 到 j 的字符串元素连接起来。元素之间由 sep 分隔(默认为空字符串)。i 默认为 1,j 默认为 #list。 |
table.insert(list, [pos,] value) | 在 list 中插入 value 到 pos 位置。如果省略 pos,则插入到末尾。后续元素会向后移动。 |
table.remove(list [, pos]) | 从 list 中移除 pos 位置的元素。如果省略 pos,则移除最后一个元素。返回被移除的元素。后续元素会向前移动。 |
table.sort(list [, comp]) | 原地(in place)对 list 中的元素进行排序。可以提供一个可选的比较函数 comp(a,b),如果 a 应该在 b 之前,则该函数应返回 true。 |
table.pack(...) | (Lua 5.2+)返回一个新表,其中所有参数存储在键 1、2 等位置,并有一个字段 ‘n’ 包含参数总数。 |
table.unpack(list [, i [, j]]) | (Lua 5.1 是 unpack,Lua 5.2+ 是 table.unpack)将给定 list 中从索引 i 到 j 的元素作为独立的返回值返回。i 默认为 1,j 默认为 #list。 |
注意:table.maxn 在 Lua 5.1 中已弃用,在 Lua 5.2 中已移除。要获取序列类表(从索引 1 开始且没有 nil 空洞的数组)的长度,请使用长度运算符 #。
表操作示例:
表连接 (table.concat)
Section titled “表连接 (table.concat)”local words = {"Lua", "is", "awesome"}print("Concatenated (default): " .. table.concat(words)) -- Luaisawesomeprint("Concatenated with space: " .. table.concat(words, " ")) -- Lua is awesomeprint("Concatenated with dash (subset): " .. table.concat(words, "-", 2, 3)) -- is-awesome插入和移除 (table.insert, table.remove, # 运算符)
Section titled “插入和移除 (table.insert, table.remove, # 运算符)”local fruits = {"banana", "orange", "apple"}print("Initial #fruits:", #fruits) -- Initial #fruits: 3
-- Insert at the endtable.insert(fruits, "mango")print("Fruit at index 4:", fruits[4], "(#fruits:", #fruits .. ")") -- Fruit at index 4: mango (#fruits: 4)
-- Insert at a specific positiontable.insert(fruits, 2, "grapes")print("Fruit at index 2:", fruits[2], "(#fruits:", #fruits .. ")") -- Fruit at index 2: grapes (#fruits: 5)-- fruits is now: {"banana", "grapes", "orange", "apple", "mango"}
local removed_fruit = table.remove(fruits) -- Removes last element ("mango")print("Removed last fruit:", removed_fruit, "(#fruits:", #fruits .. ")") -- Removed last fruit: mango (#fruits: 4)-- fruits is now: {"banana", "grapes", "orange", "apple"}
local removed_at_pos = table.remove(fruits, 1) -- Removes first element ("banana")print("Removed fruit at pos 1:", removed_at_pos, "(#fruits:", #fruits .. ")") -- Removed fruit at pos 1: banana (#fruits: 3)-- fruits is now: {"grapes", "orange", "apple"}表排序 (table.sort)
Section titled “表排序 (table.sort)”local numbers = {5, 1, 100, 20, 3}
-- Default sort (ascending)table.sort(numbers)print("Sorted numbers (ascending):")for i, v in ipairs(numbers) do print(string.format(" [%d] = %d", i, v)) end-- Output: [1]=1, [2]=3, [3]=5, [4]=20, [5]=100
-- Custom sort (descending)local names = {"Charlie", "Alice", "Bob"}table.sort(names, function(a, b) return a > b end) -- Sort descendingprint("\nSorted names (descending):")for i, v in ipairs(names) do print(string.format(" [%d] = %s", i, v)) end-- Output: [1]=Charlie, [2]=Bob, [3]=AliceLua 提供了两个主要的迭代器(iterators)用于遍历表:
- **
ipairs(t):**遍历表t中整数键1, 2, ...(序列部分),直到第一个nil值。适用于数组。 - **
pairs(t):**以未指定顺序遍历表t中的所有键值对。用于字典类表或需要访问所有元素(包括非序列部分)时。
local mixed_table = { [1] = "first", [2] = "second", name = "My Table", [4] = "fourth after nil", -- ipairs will stop before this color = "blue"}mixed_table[3] = "third" -- now sequence is 1,2,3
print("\nIterating with ipairs (sequence part):")for index, value in ipairs(mixed_table) do print(string.format(" Index: %s, Value: %s", tostring(index), tostring(value)))end
print("\nIterating with pairs (all elements):")for key, value in pairs(mixed_table) do print(string.format(" Key: %s, Value: %s", tostring(key), tostring(value)))end更多资源:表是一个广泛的主题。官方 Lua 参考手册是关于表行为、构造器和 table 库所有细节的权威来源。