如何在Lua中将函数作为参数传递?

20
block_basic_DEF =
{
    image = "button.png",
    name = "basic block",
    obj_table = this_obj_table.common_objects_table,
    startup = function() init(), <----- This is the problem
}

在另一个文件中,我像预期的那样访问:

function spawn(params)
    local obj = display.newImage(params.image)
    -- etc.
在那个 block_basic_DEF 中,我希望传递 init() 函数的地址,以便在我的生成中可以这样做: params.startup() -- 也就是实际调用原始的 init 函数。

2
“Have a def thus”不是“def”。Lua没有“定义(definitions)”。那是一个表(table),是一个值(value)。就像函数一样。 - Nicol Bolas
params.startup() 实际上将 params 引用的值视为一个表,并使用字符串 startup 对其进行索引以获取其值(点运算符)。然后,它将该值作为函数调用(括号运算符)。该函数随后将引用 init 的值作为函数调用。 - Tom Blodget
2个回答

25
Lua函数只是值,您可以使用它们的名称分配它们,而无需使用括号:
function init() 
     print("init");
end

block = { 
     startup = init
}

然后像调用普通函数一样调用它

block.startup()

它与面向对象编程(OOP)相似,但实际上就像一个函数是一个普通值一样简单。

如果你想要更类似于lambda的东西,你必须完整地拼写整个函数,省略名称:

startup = function() print("init") end

谢谢!问题在于我的init()函数在引用它之后才被定义。我更喜欢将定义和数据放在文件的顶部而不是散布在整个文件中(总是看起来很凌乱)。我该如何进行前向引用?干杯 - Mark Hula
1
正确使用Lambda函数并不会让代码变得混乱。是时候放弃古老的C语言惯用法,向前迈进了 :) - Bartek Banachewicz
@MarkHula:对于前向引用,您需要在文件顶部声明要使用的变量。如果是局部变量,可以使用local var1,var2,var3行进行声明。如果声明太多名称很丑陋,您可以声明一个单独的“命名空间”表local M = {},然后将字段用作变量:M.var1 = ...。最后,全局变量也可以像这样工作,只是命名空间表是隐式的。 - hugomg

7
你只是忘记了end关键字。它是函数定义的一部分,你不能漏掉它。在C语言中,你也不会漏掉闭合的}对吧?
block_basic_DEF =
{
    image = "button.png",
    name = "basic block",
    obj_table = this_obj_table.common_objects_table,
    startup = function() init() end, -- <-- This was the problem
}

除此之外,以下两种语法变体是相等的:
function foo()
end

foo = function()
end

1
然而,如果你要声明一个“本地函数”,语法并不完全相同。为了能够递归调用函数,你需要在赋值之前声明变量:local foo; foo = function() end - hugomg
这也正是为什么代码示例中没有“local”的原因 ;) - dualed

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