string类型作为Lua中几种基本数据类型之一,使用频率那是相当的高,所以了解Lua中字符串的实现原理,能够让我们更合理、更高效的使用Lua中的字符串。避免一些误区,提高程序效率。这里介绍的所有代码都基于Lua5.1版本。
一、Lua中string的数据结构
一般来说,要表示一个字符串一般都需要两个关键数据:
(1)字符串的长度
(2)指向字符串首地址的指针。
Lua中的字符串结构设计也是围绕这两个关键数据的。具体我们来看一下Lua中字符串的数据结构:
//(lobject.h)
/*
** String headers for string table
*/
typedef union TString {
L_Umaxalign dummy; /* ensures maximum alignment for strings */
struct {
CommonHeader;
lu_byte reserved;
unsigned int hash;
size_t len;
} tsv;
} TString;
接下来我们来理解一下这个共同体(union)中每个字段的含义:
dummy :表示字符串最大的对齐长度。L_Umaxalign也是一个共同体,具体结构如下:
//(llimits.h)
/* type to ensure maximum alignment */
typedef LUAI_USER_ALIGNMENT_T L_Umaxalign;
//(luaconf.h)
/*
@@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment.
** CHANGE it if your system requires alignments larger than double. (For
** instance, if your system supports long doubles and they must be
** aligned in 16-byte boundaries, then you should add long double in the
** union.) Probably you do not need to change this.
*/
#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; }
上面的注释解释的非常清楚了。可以根据系统需要在这个修改最大的对齐长度。
CommonHeader:表示string是需要加入到Lua的GC管理中的。CommonHeader是个宏定义,具体的介绍可以看之前的Lua数据类型(源码解析)
reserved:这个变量用于标记这个字符串是不是Lua虚拟机中的保留字符串。如果这个值不为0,那么将不会在GC阶段被回收,而是一直保留在虚拟机中。只有Lua语言中的关键字才会是保留字符串(eg.local self function)
hash:该字符串的散列值。
len:字符串的长度
二、Lua中string类型的实现
在Lua中,每个字符串数据都只有一份。每当创建一个新的字符串的时候,首先会检查当前是否已经存在这个字符串,如果存在就直接复用,让字符串变量保存这个字符串的引用,不存在则创建一个新的字符串。例如:
a = "1"
a = a..&#