function bind(func, ...) return function(...) func(..., ...) end end首先,你错过了关闭绑定功能的结束.
如果您有歧义,只需使用不同的名称解决它们.
function bind(func, ...) return function(...) func(..., ...) end end
如果我们测试你的代码:bind(print,“a”,“b”,“c”)(1,2,3)
你会得到输出:
1 1 2 3
如果在函数参数列表中有…或任何其他名称,则该变量将是该函数范围内的本地变量.它优先于优越范围内具有相同名称的任何其他变量.所以…在你的匿名函数中与函数绑定无关.
要解决此问题,您可以简单地执行类似的操作
function bind(func, ...) local a = table.pack(...) return function(...) func(table.unpack(a, 1, a.n), ...) end end
现在调用bind(print,“a”,“b”,“c”)(1,2,3)将输出:
a 1 2 3
要了解b和c发生了什么,请阅读本节:https://www.lua.org/manual/5.3/manual.html#3.4.11
(当然还有Lua手册的其余部分)
When a function is called, the list of arguments is adjusted to the
length of the list of parameters, unless the function is a vararg
function, which is indicated by three dots (‘…’) at the end of its
parameter list. A vararg function does not adjust its argument list;
instead, it collects all extra arguments and supplies them to the
function through a vararg expression, which is also written as three
dots. The value of this expression is a list of all actual extra
arguments, similar to a function with multiple results. If a vararg
expression is used inside another expression or in the middle of a
list of expressions, then its return list is adjusted to one element.
If the expression is used as the last element of a list of
expressions, then no adjustment is made (unless that last expression
is enclosed in parentheses).
所以像func(…,…)这样的东西永远不会起作用,即使……是两个不同的列表.
为避免这种情况,您必须连接两个参数列表.
function bind(func, ...) local args1 = table.pack(...) return function(...) local args2 = table.pack(...) for i = 1, args2.n do args1[args1.n+i] = args2[i] end args1.n = args1.n + args2.n func(table.unpack(args1, 1, args1.n)) end end
bind(print,“a”,nil,“c”)(1,nil,3)
这最终给了我们想要的输出:
a nil c 1 nil 3
但我相信你可以想出一个更好的方法来实现你的目标,而不是连接各种varargs.