Lua語言輸出table方法(dump工具)

版權聲明:
本文為博主原創文章,轉載請注明出處: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,那就看著很奇怪了。時間總是花在細節上。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容