概述
Lua完全采用8位编码,Lua字符串中的字符可以具有任何数值编码,包括数值0。也就是说,可以将任意二进制数据存储到一个字符串中。Lua的字符串是不可变的值(immutable values)。如果修改,实质上是新建一个字符串。根据上文《Lua中数据类型的源码实现》中知道,在Lua中,字符串是自动内存管理机制所管理的对象,并且由联合体TString来实现存储字符串值的。下面将通过Lua 5.2.1的源码来看字符串的实现以及总结了在Lua中使用字符串的注意事项。
源码实现
首先来看字符串对应的数据结构TString,其源码如下(lobject.h):
410 /*
411 ** Header for string value; string bytes follow the end of this structure
412 */
413 typedef union TString {
414 L_Umaxalign dummy; /* ensures maximum alignment for strings */
415 struct {
416 CommonHeader;
417 lu_byte extra; /* reserved words for short strings; "has hash" for longs */
418 unsigned int hash;
419 size_t len; /* number of characters in string */
420 } tsv;
421 } TString;
对这个联合体定义,有几点值得说明:
I、联合体TString中成员L_Umaxalign dummy是用来保证与最大长度的C类型进行对齐,其定义如下(llimits.h):
48 /* type to ensure maximum alignment */
49 #if !defined(LUAI_USER_ALIGNMENT_T)
50 #define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; }
51 #endif
52
53 typedef LUAI_USER_ALIGNMENT_T L_Umaxalign;
在其他可会回收的对象(比如table)的实现中,也可看到这个联合体成员,这样做的目的是通过内存对齐,加快CPU访问内存的速度。
II、联合体中成员tsv才是真正用来实现字符串的。其中成员CommonHeader用于GC,它会以宏的形式在所有的可回收对象中定义,代码如下(lobject.h):