写个 lua 打印 table 表函数

本文介绍了一个Lua脚本,用于解析Lua的debug库中getregistry()函数返回的注册表信息。该脚本通过递归方式遍历表并处理可能存在的循环引用。

今天本来是在看lua 的debug库,看到

--[[ debug.getregistry()
     函数返回Lua的注册表信息"registry"。]]

然后比较好奇这个注册表的内容是什么,就自己写了个打印lua table表的函数。

一开始没考虑table表循环的问题,写了个测试,在没有循环的情况下还行,但debug.getregistry()返回的表是有循环的。
然后在网上找来写资料,看有没哟能用的,发现都不满足自己的想法,所以还是自己写个把。用lua5写的,不一定符合所有人的需求,仅当做个记录。最终的方案如下:

-- 将值转换成字符串
function Val2Str(value)
    local value_cach = {}   -- 防止闭环
    local tinsert = table.insert
    local tconcat = table.concat
    local sformat = string.format
    local sgsub = string.gsub
    function _Val2Str(value, prefix)
        local str = ""
        local tbList = {}
        local oldprefix = prefix or ""
        prefix = oldprefix.."   "
        local value_type = type(value)
        if value_type == "table" then
            local value_name = tostring(value)
            if value_cach[value] then
                -- 循环打印,直接用table的地址,并给个提示
                return sformat("\"%s\" , -- loop table", value_name)
            end

            value_cach[value] = 1
            tinsert(tbList, sformat("%s--%s", '{', value_name))
            for k, v in pairs(value) do 
                local temp = _Val2Str(v, prefix)
                local key
                if type(k) == "number" then
                    key = sformat("[%s]", k)
                else
                    key = sformat("[\"%s\"]", tostring(k))
                end
                local line = sformat("%s%s = %s,", prefix, key, temp)
                tinsert(tbList, line)
            end
            tinsert(tbList, oldprefix..'}')
        elseif value_type == "number" then
            tinsert(tbList, tostring(value))
        elseif value_type == "string" then
            local temp = tostring(value)
            temp = sgsub(temp, "\\", "\\\\")
            temp = sgsub(temp, "\n", "\n"..prefix.."    ")
            local temp = sformat("[==[%s]==]", temp)
            tinsert(tbList, temp)
        else
            -- 非数字和字符串的,直接调用tosgring获取显示值
            local temp = sformat("\"%s\"", tostring(value))
            tinsert(tbList, temp)
        end

        str = tconcat(tbList, "\n")
        return str
    end
    local str = _Val2Str(value)
    print(str)
    return str
end

-- 进行转换
local t_registry = debug.getregistry()
local s_registry = Val2Str(t_registry)

打印出来的内容有点多,就不贴出来了。

Lua打印一个table)的内容,可以通过遍历的键值对并逐个输出来实现。由于 Lua 的 `print` 函数无法直接输出结构,因此需要手动编遍历逻辑或使用辅助函数来格式化输出。 ### 遍历的基本方式 可以使用 `pairs` 或 `ipairs` 函数来遍历中的元素。其中 `pairs` 用于遍历所有键值对,而 `ipairs` 适用于数组形式的(即索引从 1 开始的连续整数索引)。 以下是一个简单的遍历示例: ```lua local mytable = { name = "Alice", age = 25, city = "Beijing" } for key, value in pairs(mytable) do print(key, value) end ``` 该代码会输出: ``` name Alice age 25 city Beijing ``` ### 打印嵌套 如果中包含嵌套结构,例如中包含其他,则需要递归地进行遍历和打印。以下是一个支持嵌套打印函数示例: ```lua function print_table(t, indent) indent = indent or 0 for k, v in pairs(t) do local formatting = string.rep(" ", indent) .. k .. ": " if type(v) == "table" then print(formatting) print_table(v, indent + 1) else print(formatting .. tostring(v)) end end end -- 示例调用 local nestedTable = { user = { name = "Bob", age = 30 }, location = { city = "Shanghai", zip = 200000 } } print_table(nestedTable) ``` 该函数通过递归处理嵌套,并以缩进的方式提升可读性。 ### 使用元控制打印内容 Lua 允许通过元(metatable)定义 `__tostring` 方法,从而自定义对象的字符串示形式。当使用 `print` 函数输出一个时,如果该具有元且元中定义了 `__tostring` 方法,则会调用该方法[^5]。 以下是一个示例: ```lua local person = { name = "Charlie", age = 35 } local mt = { __tostring = function(t) return "Name: " .. t.name .. ", Age: " .. t.age end } setmetatable(person, mt) print(person) -- 输出:Name: Charlie, Age: 35 ``` 这种方法适用于希望将特定类型的以固定格式输出的场景。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值