Lua的table(表)

server/2025/3/6 3:20:01/

Lua表的基本概念

Lua中的表(table)是一种多功能数据结构,可以用作数组、字典、集合等。表是Lua中唯一的数据结构机制,其他数据结构如数组、列表、队列等都可以通过表来实现。

表的实现

Lua的表由两部分组成:

  1. 数组部分:用于存储整数键值对,类似于数组。

  2. 哈希部分:用于存储非整数键值对,类似于字典。

内存分配 

 Lua表的内存分配是动态的,随着元素的增加或减少,表的大小会自动调整。以下是内存分配的关键点:

  1. 初始大小

    • 新创建的表初始时数组部分和哈希部分都为空。

    • 当插入第一个元素时,Lua会根据元素类型决定将其放入数组部分还是哈希部分。

  2. 动态调整

    • 数组部分:当数组部分元素数量超过当前容量时,Lua会重新分配更大的数组,通常容量会翻倍。

    • 哈希部分:当哈希部分的负载因子(元素数量与桶数量的比值)超过某个阈值时,Lua会重新分配更大的哈希表,通常容量也会翻倍。

  3. 重新哈希

    • 当表的大小发生变化时,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内部的抽象图:


http://www.ppmy.cn/server/171889.html

相关文章

塔能科技:工厂智慧照明,从底层科技实现照明系统的智能化控制

在全球节能减碳和智慧生活需求激增的背景下&#xff0c;基于“用软件定义硬件&#xff0c;让物联运维更简捷更节能”的产品理念&#xff0c;塔能科技的智慧照明一体化方案如新星般崛起&#xff0c;引领照明行业新方向。现在&#xff0c;我们来深入探究其背后的创新技术。该方案…

应对现代生活的健康养生指南

在科技飞速发展的现代社会&#xff0c;人们的生活方式发生了巨大改变&#xff0c;随之而来的是一系列健康问题。快节奏的生活、高强度的工作以及电子产品的过度使用&#xff0c;让我们的身体承受着前所未有的压力。因此&#xff0c;掌握正确的健康养生方法迫在眉睫。 针对久坐不…

服务器间免密登录

1. 生成SSH密钥对 在本地客户端生成SSH密钥对。生成密钥对命令为&#xff1a; ssh-keygen -t rsa 按回车键确认默认设置&#xff0c;生成的密钥对将保存在 ~/.ssh/id_rsa&#xff08;私钥&#xff09;和 ~/.ssh/id_rsa.pub&#xff08;公钥&#xff09;。 2. 上传密钥对至需…

从入门到精通:Linux 权限管理(rwx/chmod/chown)

目录 1. 引言&#xff1a;为什么需要文件权限&#xff1f; 2. 基础概念&#xff1a;理解 rwx 权限 &#xff08;1&#xff09;权限的三种角色 &#xff08;2&#xff09;权限的三种类型 &#xff08;3&#xff09;权限的两种表示法 &#xff08;4&#xff09; 目录的 rwx…

多个pdf合并成一个pdf的方法

将多个PDF文件合并优点&#xff1a; 能更容易地对其进行归档和备份.打印时可以选择双面打印&#xff0c;减少纸张的浪费。比如把住宿发票以及滴滴发票、行程单等生成一个pdf&#xff0c;双面打印或者无纸化办公情况下直接发送给财务进行存档。 方法: 利用PDF24 Tools网站 …

RabbitMQ系列(七)基本概念之Channel

RabbitMQ 中的 Channel&#xff08;信道&#xff09; 是客户端与 RabbitMQ 服务器通信的虚拟会话通道&#xff0c;其核心作用在于优化资源利用并提升消息处理效率。以下是其核心机制与功能的详细解析&#xff1a; 一、Channel 的核心定义 虚拟通信链路 Channel 是建立在 TCP 连…

Qt显示一个hello world

一、显示思路 思路一&#xff1a;通过图形化方式&#xff0c;界面上创建出一个控件显示。 思路二&#xff1a;通过编写C代码在界面上创建控件显示。 二、思路一实现 点开 Froms 的 widget.ui&#xff0c;拖拽 label 控件&#xff0c;显示 hello world 即可。 qmake 基于 .…

解决Vscode项目同时运行两个项目终端无法自动叠加的问题

终端&#xff08;如命令行工具或服务进程&#xff09;无法自动“叠加”使用同一资源&#xff08;如端口号、进程ID等&#xff09;的核心原因在于操作系统的资源管理机制和网络协议规范的限制。以下是具体分析&#xff1a; 以下是解决 VSCode 同时运行两个项目时终端被前一个占…