评估存储在Lua表中的if语句

huangapple go评论63阅读模式
英文:

Evaluate if statements stored in Lua table

问题

非常初学Lua。
我想将一些if语句存储在Lua表中,并返回与之匹配的语句的结果。例如:

table = {
1 "if foo == bar1 then result = alice return result end",
2 "if foo == bar2 then result = bob return result end"
}


如何遍历该表并返回与之匹配的语句的结果?我认为可以尝试以下方式:

function get_result(foo, bar1, bar2)
for k, v in pairs(table) do
某些操作
end
end

英文:

Very much a Lua beginner here.
I would like to store some if statements in a Lua table and return the result of whichever statement matches. EG:

table = {
  [1] "if foo == bar1 then result = alice return result end",
  [2] "if foo == bar2 then result = bob return result end"
}

How do I iterate over the table and return the result of only the statement that matches? I think I something like below?

function get_result(foo, bar1, bar2)
  for k, v in pairs(table) do
    something
  end
end

答案1

得分: 3

load 函数可用于评估任意 Lua 代码,称为

其第四个参数可用于为块提供环境,从而更好地控制上值的存在(参见:sandbox)。

成功时,load 返回一个函数。调用这个函数会运行编译后的块。您可能希望使用 pcall 阻止块中的任何错误传播到调用上下文。

在语法错误的情况下,load 返回 nil 和一个错误消息。

在这个示例中,'alice''bob' 是字符串。它们也可以在环境表中定义(alice = ...)以使您的示例中的 return alice 有效。

local function get_result(foo, bar1, bar2)
    local evals = {
        "if foo == bar1 then return 'alice' end",
        "if foo == bar2 then return 'bob' end"
    }

    for index, code in ipairs(evals) do
        local chunk, err = load(code, tostring(index), "t", {
            foo = foo,
            bar1 = bar1,
            bar2 = bar2
        })

        if chunk then
            local status, result = pcall(chunk)

            if status and result then
                print(result)
            end
        else
            error(err)
        end
    }
end

get_result("a", "a", "b")
print("------")
get_result("b", "a", "b")

输出:

alice
------
bob

如果上述方法似乎是一个复杂的方式来返回两个(或多个)值之一,那么您可能正在经历一个 XY 问题

您可能希望寻找一个简单的查找表(感谢 @Aki)。

下面的示例实现了与前一个示例相同的结果:

local function get_result(foo, bar1, bar2)
    local lookup = {
        [bar1] = "alice",
        [bar2] = "bob"
    }

    local result = lookup[foo]

    if result then
        print(result)
    end
}

get_result("a", "a", "b")
print("------")
get_result("b", "a", "b")

输出:

alice
------
bob
英文:

The load function can be used to evaluate arbitrary Lua code, known as a chunk.

Its fourth argument can be used to provide the environment for the chunk, which gives better control over the upvalues present (see: sandbox).

On success, load returns a function. Calling this function runs the compiled chunk. You may want to stop any errors in the chunk from propagating to the calling context by using pcall.

On syntax error, load returns nil and an error message.

In this example, 'alice' and 'bob' are strings. They could also be defined within the environment table (alice = ...) to enable the validity of return alice from your example.

local function get_result(foo, bar1, bar2)
    local evals = {
        "if foo == bar1 then return 'alice' end",
        "if foo == bar2 then return 'bob' end"
    }

    for index, code in ipairs(evals) do
        local chunk, err = load(code, tostring(index), "t", {
            foo = foo,
            bar1 = bar1,
            bar2 = bar2
        })

        if chunk then
            local status, result = pcall(chunk)

            if status and result then
                print(result)
            end
        else
            error(err)
        end
    end
end

get_result("a", "a", "b")
print("------")
get_result("b", "a", "b")

Output:

alice
------
bob

If the above seems like an unwieldy way to yield one of two (or more) values, then you are probably experiencing an XY Problem.

You may instead be looking for a simple lookup table (cheers to @Aki).

The following example achieves the same results as the previous:

local function get_result(foo, bar1, bar2)
    local lookup = {
        [bar1] = "alice",
        [bar2] = "bob"
    }

    local result = lookup[foo]

    if result then
        print(result)
    end
end

get_result("a", "a", "b")
print("------")
get_result("b", "a", "b")

Output:

alice
------
bob

答案2

得分: 0

好的 - 我已经进行了一些调整,我的解决方案是...

-- alicebob.lua -- Lua 5.4
local table = { -- 不要重新定义全局表Library 评估存储在Lua表中的if语句
1 = [[foo = foo == ''bar1'' and 'Alice' ]],
2 = [[foo = foo == ''bar2'' and 'Bob' ]]
}

-- 让load()成为字符串数据类型的方法
string.load = load

-- 为Alice定义全局foo
foo = ''bar1''
table1:load()()
print(foo)
-- 应该打印:Alice
-- 现在为Bob设置foo
foo = ''bar2''
table2:load()()
print(foo)
-- 清理以供collectgarbage()使用
string.load = nil
foo = nil
-- alicebob.lua的结尾
€ lua alicebob.lua
Alice
Bob


<details>
<summary>英文:</summary>

OK - I played around with it and my Solution is...

€ cat alicebob.lua
-- alicebob.lua -- Lua 5.4
local table = { -- Dont redefine the global table Library 评估存储在Lua表中的if语句
1 = [[foo = foo == 'bar1' and 'Alice']],
2 = [[foo = foo == 'bar2' and 'Bob']]
}

-- Let load() be a method for Datatype String
string.load = load

-- Define global foo for Alice
foo = 'bar1'
table1:load()()
print(foo)
-- Should print: Alice
-- Now set foo to do above for Bob
foo = 'bar2'
table2:load()()
print(foo)
-- clean up for collectgarbage()
string.load = nil
foo = nil
-- End of alicebob.lua
€ lua alicebob.lua
Alice
Bob


</details>



huangapple
  • 本文由 发表于 2023年2月23日 20:35:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/75544928.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定