通过本章的学习,你可以掌握table的嵌套遍历,table内部无论嵌套多少层table都可以。
重写的print,你无论写多少个参数和多少个嵌套table都可以输出内容。
g_stringA 是笔者库中的一个字符串类, 直接使用下面的代码编译不通过,将g_stringA替换为别的类.
GxxLuaManager::GetStringFromLua 替换为 lua_tostring
看完下方代码,你应该可以理解嵌套遍历table的逻辑了。
void gxx_table_to_str( lua_State* L, int idx, g_stringA& res)
{
if (!lua_istable(L, idx))
{
return;
}
else {
res.AppendChar('{');
// 将table拷贝到栈顶
lua_pushvalue(L, idx);
int it = lua_gettop(L);
// 压入一个nil值,充当起始的key
lua_pushnil(L);
while (lua_next(L, it))
{
// 现在的栈:-1 => value; -2 => key; index => table
// 拷贝一份 key 到栈顶,然后对它做 lua_tostring 就不会改变原始的 key 值了
lua_pushvalue(L, -2);
// 现在的栈:-1 => key; -2 => value; -3 => key; index => table
if (!lua_istable(L, -2))
{
// 不是table就直接取出来就行
const char* key = lua_tostring(L, -1);
if(lua_isboolean(L, -2))
res.AppendFormat("%s=%s,", key, lua_toboolean(L, -2) ? "true" : "false");
else if(lua_isfunction(L, -2))
res.AppendFormat("%s=%s,", key, "function");
else
res.AppendFormat("%s=%s,", key, GxxLuaManager::GetStringFromLua(L, -2));
}
else
{
const char* key = lua_tostring(L, -1);
res.Append(key);
res.AppendChar('=');
// 此刻-2 => value
gxx_table_to_str(L, -2, res);
//lua_pop(L, 1);
res.AppendChar(',');
}
// 弹出 value 和拷贝的 key,留下原始的 key 作为下一次 lua_next 的参数
lua_pop(L, 2);
// 现在的栈:-1 => key; index => table
}
// 现在的栈:index => table (最后 lua_next 返回 0 的时候它已经把上一次留下的 key 给弹出了)
res.TrimRight(',');
res.AppendChar('}');
// 弹出上面被拷贝的table
lua_pop(L, 1);
}
}
int gxx_print( lua_State* L )
{
int n = lua_gettop(L);
g_stringA strPrint;
for (int p = 1; p <= n; p++)
{
if (lua_istable(L, p))
gxx_table_to_str(L, p, strPrint);
else if(lua_isboolean(L, p))
strPrint.Append(lua_toboolean(L, p) ? "true" : "false");
else if(lua_isfunction(L, p))
strPrint.Append("function");
else
strPrint.Append(GxxLuaManager::GetStringFromLua(L, p));
strPrint.AppendChar('\t');
}
strPrint.TrimRight('\t');
TRACE(strPrint);
TRACE("\r\n");
return 0;
}
把print函数重新注册一下即可替换了
lua_register(m_L, "print", gxx_print);
执行一下lua脚本:
a = {
name = 'Guo',
age = '18',
fav = {'旅游','运动','美女'}
}
print (a)
输出结果为:
{name=Guo,age=18,fav={1=旅游,2=运动,3=美女}}