下面這個是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的大小可能出現任何結果。