Lua高级语法-第二篇

打印 table,编译级别打印

Lua 复制代码
-- 编译级别打印 table:输出元表、元方法、函数原型、Upvalue、元素类型等底层信息
function debug_print_table(t, depth_limit, processed)
    -- 初始化参数:默认最大递归深度 5,避免死循环;processed 记录已处理对象(防循环引用)
    depth_limit = depth_limit or 5
    processed = processed or setmetatable({}, {__mode = "k"}) -- 弱引用表,不影响垃圾回收

    -- 1. 基础校验:如果不是 table/function/userdata,直接打印原始值
    if type(t) ~= "table" and type(t) ~= "function" and type(t) ~= "userdata" then
        print(string.format("[%s] %s", type(t), tostring(t)))
        return
    end

    -- 2. 防循环引用:如果已处理过该对象,直接打印引用标识
    if processed[t] then
        print(string.format("[%s] <循环引用: %s>", type(t), tostring(t)))
        return
    end
    processed[t] = true -- 标记为已处理

    -- 3. 打印对象基本信息(内存地址、类型)
    local obj_info = string.format("[%s] 内存地址: %p", type(t), t)
    print(obj_info)

    -- 4. 递归打印时的缩进(按深度生成)
    local function get_indent(depth)
        return string.rep("  ", depth)
    end

    -- 5. 核心逻辑:解析编译级信息(按类型处理)
    local function parse_object(obj, depth)
        if depth > depth_limit then
            print(get_indent(depth) .. "<递归深度超限>")
            return
        end

        local obj_type = type(obj)

        -- 5.1 处理 table 类型(核心:元表、元方法、元素详情)
        if obj_type == "table" then
            -- 打印元表(编译级核心信息:table 的行为由元表控制)
            local mt = debug.getmetatable(obj)
            if mt then
                print(get_indent(depth) .. "元表 (metatable):")
                parse_object(mt, depth + 1, processed) -- 递归解析元表(元表也是 table)
            else
                print(get_indent(depth) .. "元表 (metatable): nil")
            end

            -- 打印 table 元素(非普通遍历:标注元素类型+编译级信息)
            print(get_indent(depth) .. "元素 (键: 类型=值):")
            for k, v in pairs(obj) do
                local k_type = type(k)
                local v_type = type(v)
                local key_str = string.format("[%s] %s", k_type, tostring(k))
                local val_str = ""

                -- 对值的编译级信息特殊处理(函数、userdata 等)
                if v_type == "function" then
                    -- 函数:打印参数数量、Upvalue、定义位置(编译级原型信息)
                    local func_info = debug.getinfo(v, "Slnu")
                    local param_num = func_info.nparams or 0
                    local is_vararg = func_info.isvararg and "是" or "否"
                    local upvalues = {}
                    local up_idx = 1
                    while true do
                        local up_name, up_val = debug.getupvalue(v, up_idx)
                        if not up_name then break end
                        table.insert(upvalues, string.format("%s = [%s] %s", up_name, type(up_val), tostring(up_val)))
                        up_idx = up_idx + 1
                    end
                    val_str = string.format(
                        "[function] 名称: %s | 参数数: %d | 可变参数: %s | 定义行: %d-%d | Upvalue: {%s}",
                        func_info.name or "匿名", param_num, is_vararg,
                        func_info.linedefined or -1, func_info.lastlinedefined or -1,
                        table.concat(upvalues, ", ")
                    )
                elseif v_type == "userdata" then
                    -- Userdata:打印元表(C 扩展对象的编译级关联信息)
                    local v_mt = debug.getmetatable(v)
                    val_str = string.format("[userdata] 元表: %s", v_mt and tostring(v_mt) or "nil")
                elseif v_type == "table" then
                    val_str = string.format("[table] 内存地址: %p", v)
                else
                    val_str = string.format("[%s] %s", v_type, tostring(v))
                end

                print(get_indent(depth + 1) .. key_str .. " → " .. val_str)
            end

        -- 5.2 处理 function 类型(单独传入函数时解析)
        elseif obj_type == "function" then
            local func_info = debug.getinfo(obj, "Slnu")
            print(get_indent(depth) .. "函数原型信息:")
            print(get_indent(depth + 1) .. "名称: " .. (func_info.name or "匿名函数"))
            print(get_indent(depth + 1) .. "定义文件: " .. (func_info.source or "未知"))
            print(get_indent(depth + 1) .. "定义行号: " .. (func_info.linedefined or -1) .. "-" .. (func_info.lastlinedefined or -1))
            print(get_indent(depth + 1) .. "参数数量: " .. (func_info.nparams or 0))
            print(get_indent(depth + 1) .. "支持可变参数: " .. (func_info.isvararg and "是" or "否"))
            -- 打印 Upvalue(闭包捕获的变量,编译级关键信息)
            local up_idx = 1
            print(get_indent(depth + 1) .. "Upvalue (闭包变量):")
            while true do
                local up_name, up_val = debug.getupvalue(obj, up_idx)
                if not up_name then break end
                print(get_indent(depth + 2) .. up_name .. ": [" .. type(up_val) .. "] " .. tostring(up_val))
                up_idx = up_idx + 1
            end

        -- 5.3 处理 userdata 类型(C 扩展对象,编译级关联元表)
        elseif obj_type == "userdata" then
            local ud_mt = debug.getmetatable(obj)
            print(get_indent(depth) .. "Userdata 元表:")
            parse_object(ud_mt, depth + 1, processed)
        end
    end

    -- 开始解析当前对象(初始深度 1)
    parse_object(t, 1, processed)
    print("----------------------------------------") -- 分隔线
end
function add_button()
    print('add a Button')
    
    debug_print_table(__Nova)
end

LuaRuntime(可能是ToLua)

Lua 复制代码
LuaRuntime.Instance.BindObject("gameViewController", this);//需要绑定了,才能在 .lua 调用 __Nova.gameViewController.

打印堆栈

???

相关推荐
星空露珠1 小时前
速算24点所有题库公式
开发语言·数据库·算法·游戏·lua
星空露珠8 小时前
速算24点检测生成核心lua
开发语言·数据库·算法·游戏·lua
superman超哥1 天前
Serde 性能优化的终极武器
开发语言·rust·编程语言·rust serde·serde性能优化·rust开发工具
云边散步1 天前
godot2D游戏教程系列二(5)
笔记·学习·游戏·游戏开发
云边散步1 天前
godot2D游戏教程系列二(6)
学习·游戏·游戏开发
想做后端的前端2 天前
Lua的热更新
开发语言·lua
云边散步3 天前
godot2D游戏教程系列二(4)
笔记·学习·游戏开发
澄风3 天前
Redis ZSet+Lua脚本+SpringBoot实战:滑动窗口限流方案从原理到落地
spring boot·redis·lua
Geoking.3 天前
【Redis】Redis 中的 Pipeline 与 Lua 脚本:高性能与原子性的两种武器
redis·lua
云边散步4 天前
godot2D游戏教程系列二(3)
笔记·学习·游戏·游戏开发