在Lua中同时定义和调用函数

3
在JavaScript中,可以通过定义并同时调用一个函数来快速创建闭包,如下所示:
function() {
    local something = 1;
    return function () {
        // something
    }
}()

在lua中是否可能做到同样的事情?


1
是的,完全一样的方式:(function(x) print(x*x) end)(5) - undefined
2个回答

7
是的,你可以在Lua中创建立即调用函数表达式(IIFEs)。Lua需要在函数表达式周围加上括号:(function () return 10 end)()。去掉括号,function () return 10 end(),你会得到一个语法错误。给函数命名是不可能的:(function f() return 10 end)()。命名函数语法糖实际上是将函数赋值给变量,f = function() return 10 end,而在Lua中赋值不是表达式,因此不能像调用函数那样调用。
在JavaScript中,需要在函数表达式或整个函数加上括号和函数调用括号的组合: (function () { return 10; })()(function () { return 10; }())。括号确保function () {}被解释为函数表达式而不是函数声明。第二种构造的等价物(function () return 10 end())在Lua中无效。在JavaScript中,但不是在Lua中,你可以在函数表达式中提供名称,在出现错误时堆栈跟踪会显示该名称:(function f() { return 10; })()(function f() { return 10; }())

3
作为警告,请不要忘记在IIFE之前用;来分隔最后一条语句。我一直收到很多愚蠢的错误信息,说一个表值(或另一个非函数)被调用,当Lua发现(function ... end)()是调用上面几行语句的括号时,这些错误信息就出现了。
以下是示例:
split = require('string_methods/split')

(function()
    print('hi')
    return 1 
end)()

这会返回错误:

lua: split-test.lua:2: attempt to call a table value
stack traceback:
    split-test.lua:2: in main chunk
    [C]: in ?

在使用分号明确限定IIFE之前,不再出现这种情况。

split = require('string_methods/split');

(function()
    print('hi')
    return 1 
end)()

输出:

hi

谢谢你分享这个知识。真是一个碰巧发现的非常有用的知识!在你的特定情况下,问题在于require()引入了一个表/函数,然后Lua认为紧随其后的IIFE的括号"是require()返回的函数的参数"。我怀疑你发现的问题只会在前面的语句是可以接受括号参数的情况下发生,比如require("foo")("bar") - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接