【问题标题】:Using multiple parentheses when calling a function in lua在lua中调用函数时使用多个括号
【发布时间】:2020-10-12 15:17:12
【问题描述】:

我一直在学习 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

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

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

更新: 链接到我提到的教程 - http://lua-users.org/wiki/CurriedLua

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

问题已解决。感谢您的所有回答,他们非常有帮助。

【问题讨论】:

  • 请链接您参考的教程
  • 那个例子实际上是错误的。你不能这样做,例如add5=addup(5); print(add5 (3) ()); print(add5 (2) (),因为它会打印810而不是87

标签: function syntax lua currying


【解决方案1】:

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

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

这个表达式是从左到右计算的。

调用运算符() 对其左侧的值进行操作。 所以首先我们评估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

然后返回使用addup的参数x调用的函数的返回值

return f(x)

sumf 的上值,该值在定义f 的范围内。所以每次你打电话给f,它都可以访问sum

所以n 在函数f 中变为x。由于n 是一个数值,f 会将n 添加到sum 并返回一个自身f

所以addup(1) 的计算结果是对f 的引用,一个函数值的上值sum == 1。

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

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

最后 f 用() 调用。这次nnilf 返回sum。所以addup (1) (2) (3) () 最终评估为6,因为它被交给print

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

【讨论】:

    【解决方案2】:

    类似的东西,以此类推:

    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" - 返回对本地命名空间内的函数的引用,它只是一个表。

    【讨论】:

      【解决方案3】:

      addup 只被调用一次。返回的函数 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 的返回值可以完全删除,更改为 addup 和另外 1 个调用。

      需要返回值来链接原始代码中的调用addup (1) (2) (3) (),否则语法无效。

      【讨论】:

        【解决方案4】:

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

        在 Lua 中,函数只是值。

        你可以这样称呼他们:

        print("Hello, World!")
        

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

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

        或将它们作为参数传递给其他函数并返回:

        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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-09-29
          • 2022-12-19
          • 2011-11-18
          相关资源
          最近更新 更多