如何在 Lua 中逐行运行代码(单线程)?

我在 Lua 编程方面遇到了一些困难。我发现 Lua 不像 Python 一样逐行执行代码。因此,我无法将变量更新为从循环或 if/else 语句中获取的值。值仅在 if/else 或循环块内更新,但在块后,变量返回其初始值或 nil,而不是更新后的值。我希望我表达清楚了。请帮帮我。 以下是代码片段:

local list = {}
function refresh_applist()
    apps_gen.generate(function (applist) -- 回调函数
        list = applist -- 将值分配给变量 list
        naughty.notify({text = type(list[10])}) -- 等价于 print(type(list[10]))&输出 'table'
    end)
    naughty.notify({text = type(list[10])}) -- 输出 nil
end

以下是 apps_gen.generate 的功能

function apps_gen.generate(callback)
    -- 更新类别输入的图标
    apps_gen.lookup_category_icons()

    local result = {}
    local unique_entries = {}
    local dirs_parsed = 0

    for _, dir in ipairs(apps_gen.all_menu_dirs) do
        utils.parse_dir(dir, function(entries)
            entries = entries or {}
            for _, entry in ipairs(entries) do
                -- 检查是否应将程序包含在菜单中
                if entry.show and entry.Name and entry.cmdline then
                    local unique_key = entry.Name .. '\0' .. entry.cmdline
                    if not unique_entries[unique_key] then
                        local target_category = nil
                        -- 检查程序是否落入至少一个可用类别中,将 target_category 设置为找到的第一个类别的 ID。
                        if entry.categories then
                            for _, category in pairs(entry.categories) do
                                local cat_key, cat_use =
                                get_category_name_and_usage_by_type(category)
                                if cat_key and cat_use then
                                    target_category = cat_key
                                    break
                                end
                            end
                        end

                        local name = utils.rtrim(entry.Name) or ""
                        local cmdline = utils.rtrim(entry.cmdline) or ""
                        local icon = entry.icon_path or nil
                        table.insert(result, { name = name,
                                     cmdline = cmdline,
                                     icon = icon,
                                     category = target_category })
                        unique_entries[unique_key] = true
                    end
                end
            end
            dirs_parsed = dirs_parsed + 1
            if dirs_parsed == #apps_gen.all_menu_dirs then
                callback(result)
            end
        end)
    end
end
点赞
用户2858170
用户2858170

如何在 Lua 中逐行顺序运行代码(单线程)?

Lua 脚本会逐行进行解释,因此自然而然地是按顺序执行的。你不需要进行任何操作就可以实现它。

创建一个名为 list 的本地表:

local list = {}

创建一个名为 refresh_applist 的全局函数,不需要传入参数:

    function refresh_applist()
        apps_gen.generate(function (applist)
            list = applist
            naughty.notify({text = type(applist[10])})
        end)
        naughty.notify({text = type(applist[10])}) -- 输出 nil
    end

如果稍后调用 refresh_applist,它会调用一个名为 apps_gen.generate 的函数,并将一个匿名函数作为其唯一参数。

接着它会调用 naughty.notify({text = type(applist[10])}),这可能在某个地方输出 applist[10] 的类型。实际提供的代码中不存在 applist。如果你没有提到脚本错误,那么它很可能是一个表值,否则你将不能对其进行索引,因此不会输出 nil

如果匿名函数被调用,它将把其参数 applist 分配给其上值 list,还会调用 naughty.notify({text = type(applist[10])})。但这次的 applist 是它的本地参数,不是上面未知值。

回应您的评论和修改,添加更多代码:

我无法在回调函数之外使用表“applist”。

这是因为(至少在提供的代码中)回调函数之外不存在 applistapplist 是回调函数局部范围内的函数参数。在回调外面,除非你在正确的范围内早先创建了另一个 applist,它就是 nil

由于表是按引用传递的,applist 实际上是一个对 result 的引用,其回调被调用时就传入了该引用。

当你试图在回调函数之外调用 type(applist[10]) 时,应该会得到 Lua 错误,因为你在对 nil 进行索引。

2020-06-25 09:46:31