给定带有一个参数的lua函数,是否可以将此参数绑定到固定值以获取不带参数的函数?
更一般地说,如何将lua函数的某些输入参数绑定到某些值?
答案 0 :(得分:12)
是的,这几乎可以在任何具有一等价值功能的语言中完成。
function f1(a)
return a+1
end
function bind(a)
return function() return f1(a) end
end
local f2 = bind(42)
print(f2())
-- 43
此特定示例适用于特定函数和参数数量,但可以轻松扩展为使用任意函数/参数。
答案 1 :(得分:0)
我刚刚创建了一个帮助函数来执行Boost :: bind所做的事情:
function_binder(base_function, placeholders_format, args...)
.
:表示包装器中的参数A
:代表绑定器中的参数~
:表示包装器中的所有待处理参数请参阅以下示例以便更好地理解。
local function divide(a, b)
return a / b
end
local div_by_4 = function_binder(divide, ".A", 4)
print(div_by_4(12)) -- => prints: 3
local div_12_by = function_binder(divide, "A.", 12)
print(div_12_by(4)) -- => prints: 3
local debug_print = function_binder(print, "A~", "DEBUG:")
debug_print("some logs for debug")
-- => prints: DEBUG some logs for debug
-- '~' will put all following arguments:
debug_print("some", "logs", "for", "debug")
-- => prints: DEBUG some logs for debug
local function stuff(...)
print("Args: ", ...)
end
local wrapper = function_binder(stuff, ".A..AA~", "two", "five", "six")
wrapper(1, 3, 4, 7, nil, 9)
-- => prints: 1 two 3 4 five six 7 nil 9
要做更多的OO,你可以使用调试库:
-- apply metatable to all function
debug.setmetatable(function()end, {
__index = {
bind = function_binder,
},
})
local debug_print = print:bind("A~", "DEBUG:")
debug_print("add some log")
-- => prints: DEBUG: add some log
local function packed_args_append(packed, nb_insert, ...)
nb_insert = nb_insert > 0 and nb_insert or select('#', ...)
for i = 1, nb_insert do
packed[packed.n + 1] = select(i, ...)
packed.n = packed.n + 1
end
end
-- replace table.unpack as it doesn't always handle nil values correctly..
local function unpacknil(packed)
local nb_args = packed.n
local function unpack_n(n)
if n == nb_args then
return packed[n]
end
return packed[n], unpack_n(n + 1)
end
return unpack_n(1)
end
function function_binder(self, placeholder_format, ...)
local placeholders = table.pack(...)
return function(...)
local args = {n = 0}
local arg_idx = 1
local placeholder_idx = 1
for c in placeholder_format:gmatch"." do
if c == 'A' then
packed_args_append(args, 1, placeholders[placeholder_idx])
placeholder_idx = placeholder_idx + 1
elseif c == '.' then
packed_args_append(args, 1, select(arg_idx, ...))
arg_idx = arg_idx + 1
elseif c == '~' then
packed_args_append(args, -1, select(arg_idx, ...))
break
end
end
--return self(table.unpack(args))
return self(unpacknil(args))
end
end
它与Lua 5.3完美配合
在此托管:https://github.com/Bew78LesellB/luaMiscTests/commit/e9e52aea7933b58332fff36738356f18aed3db92