当前位置 : 主页 > 网络编程 > lua >

varags函数返回vargas lambdas lua

来源:互联网 收集:自由互联 发布时间:2021-06-23
如果我想编写一个接受varargs并返回一个接受vargas的函数的函数,我会遇到歧义…例如 function bind(func, ...) return function(...) func(..., ...) end end 首先,你错过了关闭绑定功能的结束. 如果您有歧
如果我想编写一个接受varargs并返回一个接受vargas的函数的函数,我会遇到歧义…例如

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.

网友评论