文章出處

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("{\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

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("{\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


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、測試結果


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()