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
在这里,函数返回自身而没有任何值甚至是括号。我知道你可以将字符串或表格传递给一个函数,并省略括号,但这不是本案例。那么到底发生了什么?
我查看了手册,但没有发现关于这两个特性的任何内容。我真的很感谢您提供详细解释或链接到涵盖这些信息的手册。谢谢。
更新: 我参考的教程链接 - http://lua-users.org/wiki/CurriedLua
正如其中一个答案所指出的,Lua中不存在 (x)(y) 语法。它实际上是一系列函数调用。这在教程中并没有被提到,但是这是我的假设,结果证明是错误的,因此我已经将这一部分编辑了出去。
问题已解决。感谢您所有的答案,它们都非常有帮助。
局部变量 _L = {}
函数 addup(x)
局部变量 sum = 0
_L["f"] = function (n)
如果类型为"number"的话
sum = sum + n
返回 _L["f"]
否则
返回 sum
结束
结束
返回 _L["f"](x)
结束
打印(addup(1)(2)(3)()) --> 6
打印(addup(4)(5)(6)()) --> 15
"返回f" - 返回一个指向在局部命名空间中的函数的引用,它只是一个表。
在这里,一个函数返回自身,没有任何值或者括号。我知道你可以将一个字符串或者表作为参数传递给一个函数,省略括号,但在这个例子中并不是这样。那么是怎么回事呢?
在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
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)
sum 是 f 的上值,这是在定义 f 时在范围内的值。因此,每次调用 f 时,它都可以访问 sum。
因此,n 在函数 f 中变为 x。由于 n 是数字值,f 将把 n 添加到 sum 中,并返回 f 自身。
因此,addup(1) 评估为对 f 的引用,一个具有上值 sum == 1 的函数值。
现在,我们已经在 (2) 左侧有了这个返回的函数值,这是另一个对 f 的函数调用。这次,n 是 2。同样,它是一个数字,因此它将被添加到 sum 中,f 将再次返回自身。
现在,f 被 (3) 调用。同上。
最后,使用 () 调用 f。这次,n 是 nil,f 返回 sum。 因此,addup (1) (2) (3) () 最终评估为在交给 print 之前为 6。
不确定您从哪里获取该示例,但对我来说并不太合理。有更简单的方法来解释上值和闭包。这样的代码难以阅读和理解。
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

addup仅被调用了一次。返回的函数f是在每次调用addup(1)之后所调用的。sum是f的一个上值(upvalue)。一旦f被定义,每次调用f都会更新相同的sum变量。这就是函数如何记住累计总数的方法。下面是另一种编写第一个序列的方法:
local sumfunction = addup(1) --创建函数并且将其首次调用参数设为 1 sumfunction(2) --使用参数 2 调用函数并且更新 sum sumfunction(3) --再次使用参数 3 调用函数并且更新 sum print(sumfunction()) --没有参数调用函数,导致返回 sum这样做可以完全去掉
f的返回值,并只需要对addup进行一次调用就可以了。返回值是必需的,以便像原始代码中那样链式调用
addup (1) (2) (3) ()。否则,语法就是无效的。