在 lua 中调用函数时使用多个括号

Using multiple parentheses when calling a function in lua

我一直在学习柯里化 Lua 并遇到了以下代码:

function addup(x)
  local sum = 0
  local function f(n)
    if type(n) == "number" then
      sum = sum + n
      return f
    else
      return sum
    end
  end
  return f(x)
end

print(addup (1) (2) (3) ())  --> 6
print(addup (4) (5) (6) ())  --> 15

我假设 (1) (2) (3) () 部分意味着值是连续而不是同时传递给函数的。我的问题是我无法完全弄清楚这些值是如何确切地传递的以及函数如何操纵它们。所以第一个值转到 x,但是第二个会发生什么?它是否作为 n 传递给内部函数?那么第三个呢?

我的另一个问题是:

return f

这里是函数 returns 本身没有任何值甚至括号。我知道您可以将字符串或 table 传递给省略括号的函数,但这里不是这种情况。那么这是怎么回事?

我查看了手册,但没有找到关于这些功能的任何内容。我非常感谢对详细介绍此内容的手册的解释或 link。谢谢。

更新: link 转到我参考的教程 - http://lua-users.org/wiki/CurriedLua

正如其中一位回答者指出的那样,lua 中没有 (x)(y) 语法。它是什么,是一系列的函数调用。这在教程中实际上并没有提到,但这是我的假设,结果证明是错误的,所以我编辑了这一点。

问题已解决。谢谢大家的回答,很有帮助。

addup 只调用一次。 returned 函数 f 是在 addup (1)

之后每次调用的函数

sumf 的上值,一旦 f 被定义,每次调用 f 都会更新相同的 sum 变量。这就是函数记住 运行 总数的方式。

这是第一个序列的另一种写法

local sumfunction = addup(1) --Creates the function and also calls it with `1` first time sum is updated
sumfunction(2)               --Calls function with `2` updating the sum
sumfunction(3)               --Calls function with `3` updating the sum again.
print(sumfunction())         --Called with no arg causing the function to return the sum

这样做可以完全删除 f 的 return 值,更改为 addup 并再调用 1 个。

需要 return 值来像原始代码中那样链接调用 addup (1) (2) (3) (),否则语法无效。

类似这样,以此类推:

local _L = {}
function addup(x)
  local sum = 0
  _L["f"] = function (n)
    if type(n) == "number" then
      sum = sum + n
      return _L["f"]
    else
      return sum
    end
  end
  return _L["f"](x)
end

print(addup (1) (2) (3) ())  --> 6
print(addup (4) (5) (6) ())  --> 15

"return f" - returns 对本地命名空间内函数的引用,它只是一个 table.

Here a function returns itself without any value or even parentheses. I know that you can pass in a string or a table to a function omitting the parentheses but it is not the case here. So what's going on?

在 Lua 中,函数只是值。

你可以这样称呼他们:

print("Hello, World!")

但您也可以将它们分配给这样的变量:

foo = print
foo("Hello, World!")

或将它们作为参数传递给其他函数,return它们:

function call_twice(f)
   return function()
      f()
      f()
   end
end

call_twice(function()
   print("Hello, World!")
end)

事实上,

local function foo() return 42 end

只是另一种写法

local foo
foo = function() return 42 end

Lua 中没有 (x)(y) 语法。这就是为什么您在手册中找不到任何内容的原因。 (x)(y) 本身会导致语法错误

addup (1) (2) (3) () 是一系列函数调用。要理解这一点,您必须仔细阅读 addup 的代码,并意识到函数调用只不过是一个函数值,后跟调用运算符,并且函数只是您可以 return 与任何其他类型一样的值。

这个表达式是从左到右求值的。

调用运算符()对其左侧的值进行操作。 所以首先我们评估 addup(1) 调用全局函数 addup.

addup 定义了一个局部数值local sum = 0 和一个局部函数值f.

local function f(n)
    if type(n) == "number" then
      sum = sum + n
      return f
    else
      return sum
    end
  end

然后 return 是用 addup 的参数 x

调用的那个函数的 return 值
return f(x)

sumf 的上值,该值在定义 f 的范围内。所以每次你调用 f 它都可以访问 sum.

所以n在函数f中变成了x。由于 n 是一个数字值 f 会将 n 添加到 sum 和 return 本身 f.

因此 addup(1) 求值为对 f 的引用,一个上值为 sum == 1 的函数值。

现在我们在 (2) 的左侧有了这个 returned 函数值,这是对 f 的另一个函数调用。这次n2。同样它是一个数字,因此它将被添加到 sum 并且 f 将再次 return 本身。

现在用 (3) 调用 f。同上。

最后用 () 调用 f。这次nnilfreturnssum。所以 addup (1) (2) (3) () 在交给 print 之前最终计算为 6

不确定你从哪里得到这个例子,但对我来说没有太大意义。有更简单的方法来解释升值和闭包。那样的代码难读。