# 1. 一些简单的例子

 a = "abc"
print(#a)  // 3



# 当获取的是字符串的长度时直接获取字符串的len

    setnvalue(ra, cast_num(tsvalue(rb)->len));



# 我们需要了解字符串是怎么样的结构

typedef union TString
{
struct
{
lu_byte reserved;  // 设置这个是个保留字的标记位, 值会是gafqX_tokens的的第几个 + 1
unsigned int hash; // 加快查找匹配
size_t len;        // 不用\0结尾,所以需要长度
} tsv;
} TString;



# 这里回忆一下字符串是怎么创建的

TString *gafqS_newlstr(gafq_State *L, const char *str, size_t l)
{
GCObject *o;
unsigned int h = cast(unsigned int, l);
size_t step = (l >> 5) + 1;
size_t l1;
for (l1 = l; l1 >= step; l1 -= step) // 计算新字符串的哈希值
h = h ^ ((h << 5) + (h >> 2) + cast(unsigned char, str[l1 - 1]));
// lua把字符串放在strt中 取出哈希值相同的链表
for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; o != NULL; o = o->gch.next)
{
TString *ts = rawgco2ts(o);
if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0))
{
changewhite(o);
return ts;
}
}
return newlstr(L, str, l, h); // 不存在创建新的字符串
}

//如果在全局的strt中的hash没找到字符串,会创建个新的
static TString *newlstr(gafq_State *L, const char *str, size_t l, unsigned int h)
{
TString *ts;
stringtable *tb;
if (l + 1 > (MAX_SIZET - sizeof(TString)) / sizeof(char))
gafqM_toobig(L);
ts = cast(TString *, gafqM_malloc(L, (l + 1) * sizeof(char) + sizeof(TString)));
ts->tsv.len = l;
ts->tsv.hash = h;
ts->tsv.marked = gafqC_white(G(L));
ts->tsv.tt = GAFQ_TSTRING;
ts->tsv.reserved = 0;
memcpy(ts + 1, str, l * sizeof(char));
((char *)(ts + 1))[l] = '\0';
tb = &G(L)->strt;  // 打算把新创建的字符串放入strt中
h = lmod(h, tb->size);
ts->tsv.next = tb->hash[h];
tb->hash[h] = obj2gco(ts);
tb->nuse++;
if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT / 2)
gafqS_resize(L, tb->size * 2);
return ts;
}