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

在JavaScript中,可以通过同时定义和调用函数来快速创建闭包,如下所示:

function() {
    local something = 1;
    return function () {
        // something
    }
}()

在Lua中能否做到同样的事情?

点赞
用户9383219
用户9383219

是的,你可以在 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; }())

2018-12-06 22:29:19
用户17066438
用户17066438

作为一个警告,千万不要忘记在将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
2022-07-31 22:55:10