如何创建一个 Lua 方法映射表?

我想要创建一个包含另一个表中函数的表,就像这样:

party_animal = {}

function party_animal:dance()
     -- 跳舞
end

function party_animal:dance_furiously()
     -- 疯狂跳舞
end

method_map = {
    'idea_one': party_animal:dance,
    'idea_two': party_animal:dance_furiously,
}

然后,我可以像这样调用这些函数:method_map[1][2]()。当我在 : 的位置使用 . 运算符时,可以使它正常工作,但我希望可以访问 self

错误信息如下:

stdin:2: '}' expected (to close '{' at line 1) near ':'
点赞
用户4567755
用户4567755
party_animal = {}

function party_animal:dance()
     --跳舞
end

function party_animal:dance_furiously()
     --疯狂跳舞
end

method_map = {
    idea_one = party_animal.dance,
    idea_two = party_animal.dance_furiously,
}

这段代码将按预期工作。为什么?

首先,请注意,您的表格体已更改以匹配lua语法。 Piglet非常详细地指出,您得到的错误是由无效的表定义引起的。

其次,这个函数的定义

function table:foo() end

与这一个相同

function table.foo(self) end

传递函数引用不会改变其参数。第一个参数仍将是self,如果您使用:调用此函数,则method_map将作为self传递。

如果您想在method_map函数中使用party_animal作为self,则需要使用额外的函数:

method_map = {
    idea_one = function (...) return party_animal.dance(party_animal, ...) end,
    idea_two = function (...) return party_animal.dance_furiously(party_animal, ...) end,
}

【Lua 5.3参考手册 关于函数定义和调用的章节】(https://www.lua.org/manual/5.3/manual.html#3.4.11).

2017-06-01 18:53:46
用户2858170
用户2858170

从Lua参考手册中:https://www.lua.org/manual/5.3/manual.html#3.4.9

表构造器是创建表的表达式。每次评估构造器时都会创建一个新表。构造器可用于创建空表或创建表并初始化其中一些字段。构造器的一般语法为

tableconstructor ::= '{' [fieldlist] '}'
fieldlist ::= field {fieldsep field} [fieldsep]
field ::= '[' exp ']' '=' exp | Name '=' exp | exp
fieldsep ::= ','| ';'

每个形式为[exp1] = exp2的字段都向新表中添加一个具有键exp1和值exp2的条目,形式为name = exp的字段等效于["name"] = exp。最后,形式为exp的字段等效于[i] = exp,其中i是从1开始的连续整数。其他格式的字段不会影响此计数。

如下所示的表达式

method_map = {'idea_one' : party_animal:dance}

是不允许的,因为这不是有效的表构造器语法。

将冒号(:)替换为等号(=),并删除''以使其成为有效表达式。

method_map = {idea_one = party_animal:dance}将避免错误消息

stdin:2: '}' expected (to close '{' at line 1) near ':'

但是,您将看到有关缺少函数参数的另一个错误消息。

这是因为冒号运算符仅适用于函数调用和定义,而不适用于索引表元素,而这实际上是您想要做的事情。

method_map = {idea_one = party_animal.dance}不会导致任何错误。

当然,您无法通过self访问party_animal。

我们如何实现这个?调用method_map:dance()将使self引用method_map。

但是,如果我们编写以下内容

method_map = {idea_one = function () return party_animal.dance(party_animal) end}

或等效的

method_map = {idea_one = function () return party_animal:dance() end}

使用冒号运算符的语法糖,我们最终获得了我们想要的结果。

现在,如果我们调用method_map:dance(),self将引用party_animal。

2017-06-01 19:05:22