以前学习过lua,也尝试在项目中使用过,这门语言很符合我的技术审美,所以打算深入进去,这门语言有以下几个特点
- 很方便的和c交互,lua的cAPI调用逻辑简单,效率高。很方便使用
- 这是一个很小的语言,依赖少,标准库小,整个语言的实现代码不过两万多行,很方便学习。
- 在游戏领域,大有lua+c替代C++的趋势。
我不写游戏,也不会。但在我看来,游戏项目代码量,逻辑,复杂度都是远超一般项目的,lua+c的方案也会得到更大的推广。
这里主要记录一下lua的对象系统。
lua有nil、boolean、number、string、userdata、function、thread、table
8 种数据类型。代码实现时,定义了如下结构
typedef union Value{
GCObject *gc;
int b; // for boolean
lua_CFunction f;
lua_Integer i;
lua_Number n;
}Value;
typedef struct lua_TValue{
Value value__;
int tt;
}TValue;
其中TValue的定义分为两个部分,其中tt存放数据类型,value__存放各种数据。value__又可以分为两部分,可gc的数据类型使用union放在一起,剩下的是不可gc的数据。
这是c语言实现面向对象的一种方式。对外部而言,TValue是基类,真正处理数据时,根据tt存储的数据类型来决定使用Value的哪个数据部分。
对于可gc部分,则稍显复杂一些。
我们来看一下gc部分
union GCUnion{
GCObject gc;
struct TString t;
strucct Udata u;
union Closure cl;
struct Table h;
struct Proto p;
struct lua_State th;
};
#define cast_u(o) cast(union GCUnion *,(o))
...
//根据TValue取得表数据。
#define gco2t(o) cast_u(o)->h //为方便理解做了适当简化
#define hvalue(o) gco2t(o->value__).gc)//为方便理解做了适当简化
转化过程其实是 TValue --取出子结构 -->GCObject --向上强转-->GCUnion -->具体数据类型。当然其中用了小技巧,即GCObject必须始终位于数据的头部,否在向上强转会失败
typedef struct GCObject{
GCObject *next;
lu_byte tt;
lu_byte marked
}GCObject;
在这里next指针用于将数据串联起来,tt用于存放数据类型,marked用与gc算法的实现,存储gc的颜色值。