为方便调试lua程序,往往想以树的形式打印出一个table,以观其表内数据。以下罗列了三种种关于树形打印lua table的方法;
法一
local print = print local tconcat = table.concat local tinsert = table.insert local srep = string.rep local type = type local pairs = pairs local tostring = tostring local next = next function print_lua_table (lua_table, indent) if not lua_table or type(lua_table) ~= "table" then return; end indent = indent or 0 for k, v in pairs(lua_table) do if type(k) == "string" then k = string.format("%q", k) end local szSuffix = "" if type(v) == "table" then szSuffix = "{" end local szPrefix = string.rep(" ", indent) formatting = szPrefix.."["..k.."]".." = "..szSuffix if type(v) == "table" then print(formatting) print_lua_table(v, indent + 1) print(szPrefix.."},") else local szValue = "" if type(v) == "string" then szValue = string.format("%q", v) else szValue = tostring(v) end print(formatting..szValue..",") end end end
以上是一个树形打印lua table 【原方法的链接】的基本源码,虽是参考云风的方法而来,却 不能够支持表内循环(打印出来的样子还是挺符合 一般人的心里预期的);
法二
譬如一下这个例子: 因为表内引用了自身造成循环引用,所以打印方法也就成了 死循环了;
a = {} a.a = { hello = { alpha = 1 , beta = 2, }, world = { foo = "ooxx", bar = "haha", root = a, }, } a.b = { test = a.a } a.c = a.a.hello
下面是 云风大神 关于lua table树形打印的源码链接;
local print = print local tconcat = table.concat local tinsert = table.insert local srep = string.rep local type = type local pairs = pairs local tostring = tostring local next = next function print_r(root) local cache = { [root] = "." } local function _dump(t,space,name) local temp = {} for k,v in pairs(t) do local key = tostring(k) if cache[v] then tinsert(temp,"+" .. key .. " {" .. cache[v].."}") elseif type(v) == "table" then local new_key = name .. "." .. key cache[v] = new_key tinsert(temp,"+" .. key .. _dump(v,space .. (next(t,k) and "|" or " " ).. srep(" ",#key),new_key)) else tinsert(temp,"+" .. key .. " [" .. tostring(v).."]") end end return tconcat(temp,"\n"..space) end print(_dump(root, "","")) end
那么打印出来的效果是这样:
+a+hello+alpha [1] | | +beta [2] | +world+root {.} | +bar [haha] | +foo [ooxx] +c {.a.hello} +b+test {.a}
上面的方法,如果摒除去 root = a 这项元素的循环引用,可打印出来的样子是这样的:
["a"] = { ["hello"] = { ["alpha"] = 1, ["beta"] = 2, }, ["world"] = { ["bar"] = "haha", ["foo"] = "ooxx", }, }, ["c"] = { ["alpha"] = 1, ["beta"] = 2, }, ["b"] = { ["test"] = { ["hello"] = { ["alpha"] = 1, ["beta"] = 2, }, ["world"] = { ["bar"] = "haha", ["foo"] = "ooxx", }, }, },["a"] = { ["hello"] = { ["alpha"] = 1, ["beta"] = 2, }, ["world"] = { ["bar"] = "haha", ["foo"] = "ooxx", }, }, ["c"] = { ["alpha"] = 1, ["beta"] = 2, }, ["b"] = { ["test"] = { ["hello"] = { ["alpha"] = 1, ["beta"] = 2, }, ["world"] = { ["bar"] = "haha", ["foo"] = "ooxx", }, }, },
法三:
也可以利用lua的序列化将lua表转化为string,再将其给print出来;
-- 序列化tablle表--將表轉化成string function serialize(obj) local lua = "" local t = type(obj) if t == "number" then lua = lua .. obj elseif t == "boolean" then lua = lua .. tostring(obj) elseif t == "string" then lua = lua .. string.format("%q", obj) elseif t == "table" then lua = lua .. "{\n" for k, v in pairs(obj) do lua = lua .. "[" .. serialize(k) .. "]=" .. serialize(v) .. ",\n" end local metatable = getmetatable(obj) if metatable ~= nil and type(metatable.__index) == "table" then for k, v in pairs(metatable.__index) do lua = lua .. "[" .. serialize(k) .. "]=" .. serialize(v) .. ",\n" end end lua = lua .. "}" elseif t == "nil" then return nil else return "-nil-" --error("can not serialize a " .. t .. " type.") end return lua end
下面附上 lua的反序列化方法(即 将string[内容是lua table]再转会lua table)
-- 反序列化tablle表--將string轉化成table function unserialize(lua) local t = type(lua) if t == "nil" or lua == "" then return nil elseif t == "number" or t == "string" or t == "boolean" then lua = tostring(lua) else error("can not unserialize a " .. t .. " type.") end lua = "return " .. lua local func = loadstring(lua) if func == nil then return nil end return func() end