Lua的table(表)
Lua表的基本概念
Lua中的表(table)是一种多功能数据结构,可以用作数组、字典、集合等。表是Lua中唯一的数据结构机制,其他数据结构如数组、列表、队列等都可以通过表来实现。
表的实现
Lua的表由两部分组成:
-  数组部分:用于存储整数键值对,类似于数组。 
-  哈希部分:用于存储非整数键值对,类似于字典。 
内存分配
Lua表的内存分配是动态的,随着元素的增加或减少,表的大小会自动调整。以下是内存分配的关键点:
-  初始大小: -  新创建的表初始时数组部分和哈希部分都为空。 
-  当插入第一个元素时,Lua会根据元素类型决定将其放入数组部分还是哈希部分。 
 
-  
-  动态调整: -  数组部分:当数组部分元素数量超过当前容量时,Lua会重新分配更大的数组,通常容量会翻倍。 
-  哈希部分:当哈希部分的负载因子(元素数量与桶数量的比值)超过某个阈值时,Lua会重新分配更大的哈希表,通常容量也会翻倍。 
 
-  
-  重新哈希: -  当表的大小发生变化时,Lua会进行重新哈希操作,将元素重新分配到新的数组或哈希部分。 
 
-  
内存管理
Lua使用垃圾回收机制来管理内存,表不再被引用时会被自动回收。你可以通过collectgarbage函数手动触发垃圾回收。
-- 手动触发垃圾回收
collectgarbage("collect")表的构造
表示引用类型,当定义了table a,table b,在内存中就是a和b都指向同一个表,那么当b修改了表中的数据之后a表的值也会修改,当a和b都指向nil的时候,Lua发现没有指向这个表的变量,那么就会自动回收,下面是实例代码:
local a = { ['s'] = 1, 54, ['k'] = 2 }
local b = a
print(a['s'])
a['s'] = 3
print(b['s'])
table的for循环写法
从table结构体分析table属性
typedef struct Table {
  CommonHeader;
  lu_byte flags;  /* 1<<p means tagmethod(p) is not present */ 
  lu_byte lsizenode;  /* 以2的lsizenode次方作为哈希表长度 */
  struct Table *metatable /* 元表 */;
  TValue *array;  /* 数组 */
  Node *node; /* 哈希表 */
  Node *lastfree;  /* 指向最后一个为闲置的链表空间 */
  GCObject *gclist;
  int sizearray;  /* 数组的大小 */
} Table;1.
-  作用:这是 Lua 中所有可垃圾回收对象的通用头部。 
-  内容: -  GCObject *next:指向下一个可垃圾回收对象,用于垃圾回收器的链表。
-  lu_byte tt:对象的类型标记(如LUA_TTABLE表示表)。
-  lu_byte marked:垃圾回收器的标记位,用于标记对象是否存活。
 
-  
2.
-  作用:标志位,用于存储表的元方法(metamethod)是否存在。 
-  细节: -  每个标志位对应一个元方法(如 __index、__newindex等)。
-  如果某一位为 1,表示对应的元方法不存在;为 0 则表示存在。 
-  例如, flags & (1 << p)可以检查第p个元方法是否存在。
 
-  
3.
-  作用:表示哈希表的大小(以 2 的幂次方表示)。 
-  细节: -  哈希表的实际大小为 2^lsizenode。
-  例如, lsizenode = 5表示哈希表有2^5 = 32个桶。
-  Lua 使用幂次方大小是为了方便哈希表的扩容和缩容。 
 
-  
4.
-  作用:指向表的元表(metatable)。 
-  细节: -  元表是 Lua 中实现面向对象编程和操作符重载的核心机制。 
-  如果 metatable为NULL,表示表没有元表。
 
-  
5.
-  作用:指向数组部分的指针。 
-  细节: -  数组部分用于存储整数键值对(从 1 开始的连续整数键)。 
-  每个元素是一个 TValue结构,存储值和类型标记。
-  如果 array为NULL,表示数组部分为空。
 
-  
6.
-  作用:指向哈希表的指针。 
-  细节: -  哈希表用于存储非整数键值对(如字符串、浮点数等键)。 
-  每个桶是一个 Node结构,包含键、值和类型标记。
-  如果 node为NULL,表示哈希部分为空。
 
-  
7.
-  作用:指向哈希表中最后一个空闲的桶。 
-  细节: -  Lua 的哈希表使用开放寻址法(open addressing)解决冲突。 
-  lastfree用于快速找到空闲的桶,避免遍历整个哈希表。
 
-  
8.
-  作用:用于垃圾回收的链表。 
-  细节: -  Lua 的垃圾回收器使用链表管理所有可回收对象。 
-  gclist指向下一个需要垃圾回收的对象。
 
-  
9.
-  作用:表示数组部分的大小。 
-  细节: -  数组部分的大小是动态调整的,随着元素的增加或减少而变化。 
-  例如, sizearray = 4表示数组部分可以存储 4 个元素(键为 1 到 4)。
 
-  
下面是table内部的抽象图:

