我知道我可以在表格中存储函数引用,并使用这里的第一个答案中描述的参数调用它们
Lua - Execute a Function Stored in a Table
但我需要在每个调用的表中存储参数。我怎么能这样做?
解释我想做什么。我想写一个转向行为课。如果您正在计算转向力,您可以调用不同的功能,如搜索(目标)或追踪(目标)。
我希望能够“收集”所有函数调用并在结束时执行它们(循环遍历表并使用存储的参数执行每个函数)或取消所有函数。
这可能吗?
答案 0 :(得分:2)
另一种(可能更清洁的)替代方案:
function verifyRequiredParams($required_fields) {
$error = false;
$error_fields = "";
$request_params = array();
$request_params = $_REQUEST;
// Handling PUT request params
if ($_SERVER['REQUEST_METHOD'] == 'PUT') {
$app = \Slim\Slim::getInstance();
parse_str($app->request()->getBody(), $request_params);
}
foreach ($required_fields as $field) {
if (!isset($request_params[$field]) || strlen(trim($request_params[$field])) <= 0) {
$error = true;
$error_fields .= $field . ', ';
}
}
if ($error) {
// Required field(s) are missing or empty
// echo error json and stop the app
$response = array();
$app = \Slim\Slim::getInstance();
$response["error"] = true;
$response["message"] = 'Required field(s) ' . substr($error_fields, 0, -2) . ' is missing or empty';
echoRespnse(400, $response);
$app->stop();
}
}
答案 1 :(得分:2)
如果已知的最大可能参数数量很少,则可以使用闭包执行简单的操作。
local function bind(f, p1, p2, p3, p4, p5)
return function()
return f(p1, p2, p3, p4, p5)
end
end
绑定后,值类型将是不可变的,并且所有参数都将被传递(甚至是nils)。
local hello = bind(print, 'hello', 123)
hello() --> hello 123 nil nil nil
当然,您也可以绑定到引用类型。
local coords = { x=0, y=0 }
local t1 = bind(function(t, n) t.x = t.x + n end, coords, 20)
local t2 = bind(function(t, n) t.y = t.y + n end, coords, 50)
t1(); print('transform1', coords.x, coords.y) --> 20 0
t2(); print('transform2', coords.x, coords.y) --> 20 50
t1(); print('transform1', coords.x, coords.y) --> 40 50
并且,您仍然可以将所有内容存储在表格中。
local t = {
bind(function(a, b) return 'add', a + b end, 5, 5),
bind(function(a, b) return 'sub', a - b end, 5, 5),
bind(function(a, b) return 'mul', a * b end, 5, 5),
bind(function(a, b) return 'div', a // b end, 5, 5),
}
for _, f in ipairs(t) do
print(f())
end
--> add 10
--> sub 0
--> mul 25
--> div 1
答案 2 :(得分:0)
如果你想在一个表中存储一个函数和一些参数,然后用这些参数调用函数,那么,你只需将参数与函数一起存储在表中,然后将它们作为参数传递:
functions_with_parameters = {
{
f = function (a, b) return a + b end,
args = { 1, 2 }
},
{
f = function (a, b) return a - b end,
args = { 100, 90 }
}
}
for _, a in pairs(functions_with_parameters) do
print(a.f(a.args[1], a.args[2]))
end
// 3
// 10
答案 3 :(得分:0)
这就是我要做的事情:
-- pack one func + args into a table
function record( f, ... )
return { func = f, n = select( '#', ... ), ... }
end
-- take a list/array/sequence of `record`ed functions & run them
function run( list )
for _, callinfo in ipairs( list ) do
callinfo.func( table.unpack( callinfo, 1, callinfo.n ) )
end
end
样品使用:
todo = { }
todo[#todo+1] = record( print, "foo", "blah", nil, 23 )
todo[#todo+1] = record( print, "baz" )
run( todo )
--> foo blah nil 23
--> baz
一些明显的变化包括在pcall
中执行run
(因此错误不会在中间中止),或者添加一个额外的函数( list, f, ... )
以及哪些包通话信息&amp;将其附加到列表中。
如果您可以确定参数列表中间没有nil
,则可以简化为......
-- pack one func + args into a table
function record( f, ... )
return { func = f, ... }
end
-- take a list/array/sequence of `record`ed functions & run them
function run( list )
for _, callinfo in ipairs( list ) do
callinfo.func( table.unpack( callinfo ) )
end
end
...但我强烈建议只在最后完成其余代码并且知道(测量!)这样做时才这样做是慢的。 (如果有一个错误将偶然的nil
引入参数列表,这个版本将更改参数列表(通过删除元素),而第一个将通过它更改无论如何,这都是调试友好的。)
如果你真的缺乏空间,你可以通过不使用该功能的命名字段来节省一个值的空间......
(附录:除了Lua 5.2之外,这似乎也比上面的其他两个版本快一点 - 请参阅下面的评论。)
-- (you can actually just do this inline)
function record( f, ... ) return { f, ... } end
-- take a list/array/sequence of `record`ed functions & run them
function run( list )
for _, callinfo in ipairs( list ) do
callinfo[1]( table.unpack( callinfo, 2 ) )
end
end
...但这取决于参数的数量,实际上可能会浪费空间! (对于x86_64上的vanilla(PUC-Rio)Lua,它为0,1,3或7个参数保存16个字节(1个TValue),对2个或6个参数不执行任何操作,4个用于浪费32个字节,5个用于16个字节8个参数的112个字节(并且相同的2次幂模式不断增长/重复)。)