我需要创建一个结构。该结构必须包含一组"布尔条件"。像这样:
function ReturnStructure ()
local structure = {
{A < 10},
{B == "smth"},
{FunctionReturnsTrueOrFalse(params)},
--...
}
return structure
end
structure = ReturnStructure()
print(structure[1][1]) -- prints true or false depending on the value of A
实际上这些表包含true或false,而不是条件,因为当我们调用函数ReturnStructure并创建一个本地表结构时,将执行字段中的所有条件。我想创建一个结构,其字段将不包含布尔值,但我可以执行(当我想这样做时)并得到一个布尔值。我可以通过使用匿名函数来实现这一点:
function ReturnStructure ()
local structure = {
{function() return A < 10 end},
{function() return B == "smth" end},
{FunctionReturnsTrueOrFalse, params}, -- I don't call function in this line, a just put its adress and parameters to table.
--...
}
return structure
end
structure = ReturnStructure()
print(structure[1][1]) -- prints function: 0x109bdd0
print(structure[1][1]()) -- prints true or false. I execute condition in this string.
所以,有一个代码可以按照我的意愿运行,但它看起来非常难看。
我想听听一些关于如何创建一个更简单,更漂亮的表的想法,而不是在每个字段中打印function () return ...
。我认为我应该使用简单的OOP实现来创建我的结构作为对象,但我不知道如何做到这一点。我也很乐意得到一些方法,实现,文章等的参考,这可以帮助我找到一些想法。
答案 0 :(得分:2)
我想听听一些关于如何创建一个更简单,更漂亮的表的想法,而不是在每个字段中打印函数()返回....
没有。如果Lua有C#的lambda语法,你可以写:
local structure = {
() => A < 10,
() => B == "smth",
() => FunctionReturnsTrueOrFalse(params),
但Lua喜欢保持简洁,避免增加语言及其实现的大小和复杂性,因此我们有一种语法用于一种函数类型。
你可以将它们存储为字符串,然后在以后编译并运行它们,但是这样就选择了表单而不是函数。你不想不必要地调用编译器。
local structure = {
'A < 10',
'B == "smth"',
'FunctionReturnsTrueOrFalse(params)',
所以你原来的解决方案更好。我并不特别喜欢前两个项目推迟评估其参数的方式,而您的第三个示例在编译时评估参数。处理FunctionReturnsTrueOrFalse
相同的
local structure = {
function() return A < 10 end,
function() return B == "smth" end,
function() return FunctionReturnsTrueOrFalse(param1) end,
这也意味着您不需要将它们放在表格中。每个只是你调用的函数,它也简化了调用代码。
如果你真的想在编译时评估FunctionReturnsTrueOrFalse
的参数,我会写一个实用例程来从函数及其参数构建一个闭包:
local function bind(f, ...)
local args = {...}
return function() f(unpack(args)) end
end
然后使用它将函数绑定到它的args:
local structure = {
function() return A < 10 end,
function() return B == "smth" end,
bind(FunctionReturnsTrueOrFalse, param1, param2, param3),
然后,表格中的所有内容都只是一个功能,因此您不需要特殊处理
答案 1 :(得分:0)
function ReturnStructure ()
local structure = {
{'A < 10'},
{'B == "smth"'},
{FunctionReturnsTrueOrFalse, 'parameter'},
}
local function call_me(f, ...)
return (type(f)=='function' and f or
assert((load or loadstring)('return '..f)))(...)
end
return setmetatable({}, {
__index =
function(t,k)
if structure[k] then
return call_me((table.unpack or unpack)(structure[k]))
end
end,
__newindex = function(t,k,v) structure[k] = v end
})
end
A = 2
B = "anything"
function FunctionReturnsTrueOrFalse(par)
return #par > 5
end
structure = ReturnStructure()
print(structure[1]) -- true
print(structure[2]) -- false
print(structure[3]) -- true
structure[4] = {'1==0'}
print(structure[4]) -- false