Lua5.3源码阅读记录(2)-- 数据类型

本文探讨了Lua5.3中实现动态类型的关键数据结构Tvalue,详细介绍了如何通过Tvalue表示各种数据类型,包括需要垃圾回收(GC)和不需要GC的类型。文章解析了Tvalue的结构,以及如何在Tvalue与具体类型之间进行转换,强调了数据结构在实现动态语言特性中的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

       首先 lua是一门动态类型的脚本语言,这就意味着同一个变量在不同的时刻可以指向不同的数据类型,例如声明一个变量t 既可以指向字符串,也可以指向表,这就需要一个通用的数据结构来表示lua里的所有数据类型包括数字、字符串、表、指针、函数、Lua虚拟机等类型。用来表示不同的数据类型的通用数据结构需要满足两个条件,1.结构中需要包含一个表示数据类型的字段 2.包含一个存储实际数据的字段 ,常见的做法有两种:

1. 一般的面向对象思路,定义一个公共数据结构,存储所有数据类型的公共信息,其他具体数据在派生结构中定义 。

2. 使用c语言的union

在lua中,两种方法都有使用,接下来看一下lua的通用数据结构是如何定义的,首先需要确定数据类型type,在lua中基础数据类型对应的type在lua.h 中定义 。如下图

 

 

其中 LUA_TUSERDATA 和 LUA_TLIGHTUSERDATA 两种 对应的都是void* 。区别在于LUA_TLIGHTUSERDATA的分配释放由lua外部的使用者来完成,不需要lua关心其生命周期 ,后者是通过lua内部完成的。

上述数据类型大体可以分为两类,需要GC的和 不需要GC的,需要GC的有LUA_TSTRING(字符串)、LUA_TTABLE(表)’LUA_TFUNCTION(函数)、LUA_TUSERDATA(指针)LUA_TTHREAD(线程),对于需要GC的数据类型,他们的公共信息是一个简单的宏定义CommonHeader,定义在lobject.h中,并定义了一个只包含CommonHeader的结构体GCObject。

lua内部通过一个这个宏来标识需要GC的数据,此处使用宏定义是为了使用上的方便 。 next :下一个GC链表的成员     tt:表示上述的数据类型,lua_byte 是unsigned char 类型的别名     marked:GC相关标记位 

接下来,Lua使用了一个联合体GCUnion来表示所有需要GC的数据类型(定义在lstate.h中)

再将需要所有需要GC的数据类型看作一种类型和 其他不需要GC的数据类型放在一起形成新的联合体Value (lobject.h)

需要注意的是:Value中存储的是一个GCObject的指针,实际指向的是一个GCUnion类型的值,这里的Value已经可以表示lua中所有数据类型的值。但还有一个问题,对于GC数据类型,在GCObject中有一个tt标识具体数据类型,而非GC数据类型却无法区分出来,所以还需要添加一个标识数据类型的字段 。也就是下面的Tvalue,其中的tt_标识了数据类型 

这个结构就跟最开始我们自己定义的TValue十分类似了。到这里我们已经可以使用TValue来表示lua的所有数据类型,紧接着就需要实现各种具体类型和TValue之间进行转换 ,lobject.h中定义了大量的TValue和具体类型相互转换的宏定义 

Tvalue -> 具体类型 

首先进行类型判断,然后根据类型取值,对于非GC数据,直接取Vlaue中对应类型的值 ,对于GC数据需要先将Vlaue中的gc转为GCUnion*  再去取值 ,例如TString类型,通过(GCUnion*)(t.value_.gc)->ts 取值 

具体类型 -> TValue

对于非gc数据,直接将值赋给对应字段,设置tt_为对应类型 ,对于gc数据类型,需要使用obj2gco将数据转换为GCObject,地址赋值给TVlaue中的gc字段,再设置tt_为对应类型 。lobject.h中主要是各种类型的数据结构定义 、类型判断函数 和 类型转换函数 。

      需要知道的是 ,程序 =  数据结构 + 算法,而TValue就是为了实现lua动态语言特性所定义的一种数据结构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值