1、前言
最近在做关于openresty方面的工作,涉及到lua脚本语言,经常需要打日志查看内容。普通的print函数遇到nil或table时,非常无力。而项目中的代码经常遇到参数为nil或table的情形。所以,如果想解决上面的问题,将整个table类型数据的结构输出到控制台,那就使用循环+递归的方式来输出数据吧。
2、函数实现
--[[ print_dump是一个用于调试输出数据的函数,能够打印出nil,boolean,number,string,table类型的数据,以及table类型值的元表 参数data表示要输出的数据 参数showMetatable表示是否要输出元表 参数lastCount用于格式控制,用户请勿使用该变量 ]] function print_dump(data, showMetatable, lastCount) if type(data) ~= "table" then --Value if type(data) == "string" then io.write(""", data, """) else io.write(tostring(data)) end else --Format local count = lastCount or 0 count = count + 1 io.write("{ ") --Metatable if showMetatable then for i = 1,count do io.write(" ") end local mt = getmetatable(data) io.write(""__metatable" = ") print_dump(mt, showMetatable, count) -- 如果不想看到元表的元表,可将showMetatable处填nil io.write(", ") --如果不想在元表后加逗号,可以删除这里的逗号 end --Key for key,value in pairs(data) do for i = 1,count do io.write(" ") end if type(key) == "string" then io.write(""", key, "" = ") elseif type(key) == "number" then io.write("[", key, "] = ") else io.write(tostring(key)) end print_dump(value, showMetatable, count) -- 如果不想看到子table的元表,可将showMetatable处填nil io.write(", ") --如果不想在table的每一个item后加逗号,可以删除这里的逗号 end --Format for i = 1,lastCount or 0 do io.write(" ") end io.write("}") end --Format if not lastCount then io.write(" ") end end
3、测试例子
--[[ print_dump是一个用于调试输出数据的函数,能够打印出nil,boolean,number,string,table类型的数据,以及table类型值的元表 参数data表示要输出的数据 参数showMetatable表示是否要输出元表 参数lastCount用于格式控制,用户请勿使用该变量 ]] function print_dump(data, showMetatable, lastCount) if type(data) ~= "table" then --Value if type(data) == "string" then io.write(""", data, """) else io.write(tostring(data)) end else --Format local count = lastCount or 0 count = count + 1 io.write("{ ") --Metatable if showMetatable then for i = 1,count do io.write(" ") end local mt = getmetatable(data) io.write(""__metatable" = ") print_dump(mt, showMetatable, count) -- 如果不想看到元表的元表,可将showMetatable处填nil io.write(", ") --如果不想在元表后加逗号,可以删除这里的逗号 end --Key for key,value in pairs(data) do for i = 1,count do io.write(" ") end if type(key) == "string" then io.write(""", key, "" = ") elseif type(key) == "number" then io.write("[", key, "] = ") else io.write(tostring(key)) end print_dump(value, showMetatable, count) -- 如果不想看到子table的元表,可将showMetatable处填nil io.write(", ") --如果不想在table的每一个item后加逗号,可以删除这里的逗号 end --Format for i = 1,lastCount or 0 do io.write(" ") end io.write("}") end --Format if not lastCount then io.write(" ") end end print("---------------Test---------------") local myData = nil print_dump(myData) print("-------------------") myData = true print_dump(myData) print("-------------------") myData = 10086 print_dump(myData) print("-------------------") myData = "your name" print_dump(myData) print("-------------------") myData = { null = nil, bool = true, num = 20, str = "abc", subTab = {"111", "222"}, func = print_dump, sunTab = {"sun_a", {"sun_1", "sun_2"}, {you = "god", i = "man"}} } local mt = {} mt.__add = function(op1, op2) return 1000 end mt.__index = {1,2} setmetatable(myData, mt) print_dump(myData, 1) -- 第二个参数不为空则打印元表 print("---------------End---------------")
4、测试结果