下面这个是c api,可以获取一个对象的大小:
LUA_API size_t lua_objlen (lua_State *L, int idx) {
StkId o = index2adr(L, idx);
switch (ttype(o)) {
case LUA_TSTRING:
return tsvalue(o)->len;
case LUA_TUSERDATA:
return uvalue(o)->len;
case LUA_TTABLE: // 看这里
return luaH_getn(hvalue(o));
case LUA_TNUMBER: {
size_t l;
lua_lock(L); /* `luaV_tostring' may create a new string */
l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0);
lua_unlock(L);
return l;
}
default:
return 0;
}
}
对于table 调用的就是luaH_getn 了。
int luaH_getn (Table *t) {
unsigned int j = t->sizearray;
if (j > 0 && ttisnil(&t->array[j - 1])) {
/* there is a boundary in the array part: (binary) search for it */
unsigned int i = 0;
while (j - i > 1) {
unsigned int m = (i+j)/2;
if (ttisnil(&t->array[m - 1])) j = m;
else i = m;
}
return i;
}
/* else must find a boundary in hash part */
else if (t->node == dummynode) /* hash part is empty? */
return j; /* that is easy... */
else return unbound_search(t, j);
}
这里有3种情况:
- array大小非0,且最后一个元素为nil。二分法确定具体位置。
- 哈希表为空。数组大小就是table大小。
- 其他。二分法在哈希表中确定具体位置。
所以,如果table不是当做数组来用,那么获取table的大小可能出现任何结果。
|
请发表评论