版權聲明:
本文為博主原創文章,轉載請注明出處:Lua語言輸出table方法(dump工具)
文章鏈接:http://www.lxweimin.com/p/ea1aaede9772
嚴厲譴責某些個人及論壇轉載博客且不標明文章為轉載內容的行為。
請支持原創,維護作者權益!
在多人合作項目中偶爾會遇到這樣的情況:
現在在調試程序,從其他小伙伴提供的方法中取到的table類型數據報錯了,此時我們想檢查一下數據格式。但是直接print又無法打印出來這個table的結構,真機測試時又不太方便在Lua中打斷點,用for循環來輸出又不能展開所有子table(有個dump工具該多好)。
所以,如果想解決上面的問題,將整個table類型數據的結構輸出到控制臺,那就使用循環+遞歸的方式來輸出數據吧。
下面直接貼上代碼以及測試用例:
感謝老司機Reyn在評論中提出的建議
--[[
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("{\n")
--Metatable
if showMetatable then
for i = 1,count do io.write("\t") end
local mt = getmetatable(data)
io.write("\"__metatable\" = ")
print_dump(mt, showMetatable, count) -- 如果不想看到元表的元表,可將showMetatable處填nil
io.write(",\n") --如果不想在元表后加逗號,可以刪除這里的逗號
end
--Key
for key,value in pairs(data) do
for i = 1,count do io.write("\t") 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(",\n") --如果不想在table的每一個item后加逗號,可以刪除這里的逗號
end
--Format
for i = 1,lastCount or 0 do io.write("\t") end
io.write("}")
end
--Format
if not lastCount then
io.write("\n")
end
end
下面分別輸出了nil,boolean,number,string,table類型的數據,測試代碼如下:
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---------------")
dump輸出的結果是這樣的(因為內容太長,屏幕高度不夠,所以分成了兩張圖):
上半部分輸出.jpeg
下半部分輸出.jpeg
如果不是有特殊需求,建議按照注釋的提示,屏蔽子級table類型值的元表。屏蔽子級table類型值的元表之后輸出看起來清爽很多。
屏蔽子級table的元表后的輸出.jpeg
總結:
其實解決問題不難,需求是成長的直接動力。
其實為了dump輸出圖上的效果,我還是花了一些時間去做微調。最初末尾是沒有換行的,也就是End那一行會緊接著上一行輸出,雖然table的結構可以正常看到,但是如果dump的不是一個table,那就看著很奇怪了。時間總是花在細節上。