会PHP的人都知道PHP中的print_r/var_export函数,可以方便的用于打印数组或导出变量,Lua中没有提供,实际应用中却是很多时候需要类似的功能。
今天便封装了个简单函数,实现类似功能,用来打印/导出table:
-- dump.lua --[[ dump对象 @param mixed obj @return string ]] function debug.dump(obj) local getIndent, quoteStr, wrapKey, wrapVal, dumpObj getIndent = function(level) return string.rep("\t", level) end quoteStr = function(str) str = string.gsub(str, "[%c\\\"]", { ["\t"] = "\\t", ["\r"] = "\\r", ["\n"] = "\\n", ["\""] = "\\\"", ["\\"] = "\\\\", }) return ‘"‘ .. str .. ‘"‘ end wrapKey = function(val) if type(val) == "number" then return "[" .. val .. "]" elseif type(val) == "string" then return "[" .. quoteStr(val) .. "]" else return "[" .. tostring(val) .. "]" end end wrapVal = function(val, level) if type(val) == "table" then return dumpObj(val, level) elseif type(val) == "number" then return val elseif type(val) == "string" then return quoteStr(val) else return tostring(val) end end dumpObj = function(obj, level) if type(obj) ~= "table" then return wrapVal(obj) end level = level + 1 local tokens = {} tokens[#tokens + 1] = "{" for k, v in pairs(obj) do tokens[#tokens + 1] = getIndent(level) .. wrapKey(k) .. " = " .. wrapVal(v, level) .. "," end tokens[#tokens + 1] = getIndent(level - 1) .. "}" return table.concat(tokens, "\n") end return dumpObj(obj, 0) end
测试代码:
-- test.lua local obj = { string1 = "Hi! My name is LiXianlin", string2 = "aa\tbb\rcc\ndd\\ee\"ff", string3 = "a\\tb\\rc\\n\\\\ee\"ff", int = 9527, float = 3.1415, bool = true, table = { 1, 2, 3, { a = 21, b = 22, c = 23, }, }, [88] = 88888, [9.7] = 22222, } print(debug.dump(obj)
输出结果:
{ ["string1"] = "Hi! My name is LiXianlin", [9.7] = 22222, ["table"] = { [1] = 1, [2] = 2, [3] = 3, [4] = { ["b"] = 22, ["a"] = 21, ["c"] = 23, }, }, ["float"] = 3.1415, ["int"] = 9527, ["string3"] = "a\\tb\\rc\\n\\\\ee\"ff", ["bool"] = true, ["string2"] = "aa\tbb\rcc\ndd\\ee\"ff", [88] = 88888, }
函数特点:
1、理论上支持无限级table嵌套
2、格式化输出,可读性好
3、输出结果可直接用于lua代码
4、function、userdata、thread类型tostring输出
5、当字符串中含有控制字符时,可能有影响(代码中仅对\t,\r,\n等进行了处理)
时间: 2024-10-05 13:53:45