lua里面Table的底层实现

本文详细介绍了Lua中的核心数据结构Table,包括它的特点、数据结构和重要操作。Table既是容器也是实现面向对象功能的基础,其内部分为数组和哈希表两部分。文章深入剖析了Table的创建、键值插入的规则以及空间动态扩展的机制,帮助读者理解Lua Table的工作原理。
摘要由CSDN通过智能技术生成

Table特点

容器功能:与其他语言相似,lua也内置了容器功能,也就是table。而与其他语言不同的是,lua内置容器只有table。正因为如此,为了适配不同的应用需求,table的内部结构也比较考究,分为了数组和哈希表两个部分,根据不同需求来决定使用哪个部分。
面向对象功能:与其他语言不同的时,lua并没有把面向对象的功能以语法的形式包装给开发者。
但是我们可以用table 完成一个类似与面相对象的操作。

Table的数据结构

1.Table结构体
table是存放在GCObject里的。结构如下:

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;

从table的结构可以看出,table在设计的时候以两种结构来存放数据。一般情况对于整数key,会用array来存放,而其它数据类型key会存放在哈希表上。并且用lsizenode作为链表的长度,sizearray作为数组长度。
2、Node结构体

typedef union TKey {
   
  struct {
   
    TValuefields;
    struct Node *next;  /* 指向下一个冲突node */
  } nk;
  TValue tvk;
} TKey;

typedef struct Node {
   
  TValue i_val;
  TKey i_key;
} Node;

Node结构很好理解,就是一个键值对的结构。主要是TKey结构,这里用了union,所以TKey的大小是nk的大小。并且实际上TValue与TValuefields是同一个结构,因此tvk与nk的TValuefields都是代表键值。而且这里有一个链表结构struct Node *next,用于指向下一个有冲突的node。

3.各成员的定义

CommonHeader:垃圾回收通用结构,详情参考本专栏数据结构篇。
flags:用于cache该表中实现了哪些元方法。
lsizenode:哈希表大小取log2(哈希表大小只会为2的次幂)
sizearray:数组大小(数组大小只会为2的次幂)
array:数组头指针
node:哈希表头指针
lastfree:哈希表可用尾指针,可用的节点只会小于该lastfree节点。
metatable:元表
gclist:GC的链表,用于垃圾回收。

Table的重要操作

1.创建table
table的创建通过lua_newtable函数实现。通过定位具体实现是在luaH_new这个函数进行table的创建。代码如下:

Table *luaH_new (lua_State *L, int narray, int nhash) {
   
  Table *t = luaM_new(L, Table);/* new一个table对象 */
  luaC_link(L, obj2gco(t), LUA_TTABLE);
  t->metatable = NULL;
  t->flags = cast_byte(~0);
  /* temporary values (kept only if some malloc fails) */
  t->array = NULL;
  t->sizearray = 0;
  t->lsizenode = 0;
  t->node = cast(Node *, dummynode);
  setarrayvector(L, t, narray);
  setnodevector(L, t, nhash);
  return t;
}

主要是对table进行初始化,其中setarrayvector是对数组大小进行设置,setnodevector是对hash表大小进行设置,具体代码如下:

/*
  设置数组的容量
*/
static void setarrayvector (lua_State *L, Table *t, int size) {
   
  int i;
  //重新设置数组的大小
  luaM_reallocvector(L, t->array, t->sizearray, size, TValue);
  //循环把数组元素初始化为nil类型
  for (i=t->sizearray; i<size; i++)
     setnilvalue(&t->array[i]);
  t->sizearray 
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值