如何在Lua中创建方法地图?

时间:2017-06-01 18:47:14

标签: lua

我想创建一个包含另一个表的函数的表,如下所示:

party_animal = {}

function party_animal:dance()
     -- dance
end

function party_animal:dance_furiously()
     -- extreme dance
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 ':'

2 个答案:

答案 0 :(得分:4)

party_animal = {}

function party_animal:dance()
     -- dance
end

function party_animal:dance_furiously()
     -- extreme dance
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传递。

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

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 Reference Manual on function defining and calling

答案 1 :(得分:4)

来自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。形式名称= exp的字段是   相当于[“name”] = exp。最后,exp形式的字段是   相当于[i] = exp,其中i是连续的整数开始   1.其他格式的字段不会影响此计数。

如你所见

method_map = {'idea_one' : party_animal:dance}

是不可能的,因为它不是表构造函数的有效语法。

替换:with =并删除''以使其成为有效的表达式。

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

  

stdin:2:'}'预期(在第1行关闭'{')靠近':'

但是你会看到另一条关于缺少函数参数的错误消息。

这是因为冒号运算符仅对函数调用和定义有效。不是为了实际想要做的索引表元素。

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

当然,你无法通过自己访问party_animal。

我们怎样才能做到这一点?调用method_map:dance()将自我引用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()

,现在自我将引用party_animal