在Lua

时间:2019-02-21 13:11:38

标签: lua lua-table

据我了解,有多种方法可以在Lua中为表定义成员函数。例如,以下两个似乎等效:

-- method a)
local table1 = {x = 1, y = 2}
function table1:myfunc()
    return self.x + self.y
end

-- method b)
local table2 = {
    x = 1,
    y = 2,

    myfunc = function(self)
        return self.x + self.y
    end,
}

以前使用过Python,我的本能是使用方法b)将事物更整齐地分组在一起。但是,通读示例,似乎人们通常按照惯例使用方法a)。我找不到任何客观原因来解释为什么它应该优越。

实际上,相反,似乎有理由在初始化表时至少向前声明函数变量,例如:

local table3 = {x = 1, y = 2, myfunc}
function table3:myfunc()
    return self.x + self.y
end

这样Lua从一开始就知道成员的存在并可以正确设置哈希,而增加现有表中成员的数量可能需要重新哈希处理(尽管我无法想象这实际上已经变成了哈希表)除非您可能对大量小表执行此操作,否则性能会明显下降)。对于来源,请进行比较:https://www.lua.org/gems/sample.pdf

那么,在表本身的定义过程中是否有没有直接定义成员函数的原因?还是仅仅是某些语法糖(function name()语法和冒号)不可用的事实?

1 个答案:

答案 0 :(得分:2)

作为一个函数式编程的书呆子,我更喜欢方法b,因为它可以一次定义所有表,而不是为我们需要添加的每种方法一次对其进行更改。您应该意识到的一件事是,某些方法可能会相互调用,并且使用本地方法比调用self:myfunc()更快。

local function myfunc(self)
  return self.x + self.y
end

local myTable = {
  x = 1,
  y = 2,
  myfunc = myfunc,

  moreMyfunc = function(self)
    return myfunc(self) * 2
  end,
}

如果方法之间缺乏对称性很麻烦,则可以使所有方法成为本地方法,并将它们添加到表构造函数中,就像我对myfunc所做的那样。

Egor提出了另一个要点(如果表是类,则更重要):

  

方法a允许您从内部访问变量table1作为高值   您的功能。方法b不允许这样做。

在这种情况下,我将转发声明表名。这样做的好处是只更改一次变量,而不是多次更改表。

local myTable

local function myfunc(self)
  return self.x + self.y
end

local function moreMyfunc(self)
  return myfunc(self) * 2
end

myTable = {
  x = 1,
  y = 2,
  myfunc = myfunc,
  moreMyfunc = moreMyfunc,
}