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.

打印堆栈

???

相关推荐
今天没有盐2 小时前
Python算法实战:从滑动窗口到数学可视化
python·pycharm·编程语言
SmalBox4 小时前
【URP】Unity[内置Shader]简单光照SimpleLit
unity3d·游戏开发·图形学
雨中飘荡的记忆5 小时前
秒杀系统设计与实现
java·redis·lua
emo了小猫1 天前
Redis 执行 Lua 脚本过程中报错,会发生什么
redis·junit·lua
软件测试雪儿2 天前
高频Postman软件测试面试题
测试工具·lua·postman
今天没有盐2 天前
Scala Map集合完全指南:从入门到实战应用
后端·scala·编程语言
龙智DevSecOps解决方案2 天前
Perforce《2025游戏技术现状报告》Part 1:游戏引擎技术的广泛影响以及生成式AI的成熟之路
人工智能·unity·游戏引擎·游戏开发·perforce
有意义3 天前
栈数据结构全解析:从实现原理到 LeetCode 实战
javascript·算法·编程语言
12程序猿3 天前
postman调用文件(.xlsm---带宏的excel文件)下载接口成功下载excel文件,浏览器访问下载文件打不开
excel·lua·postman