在 Lua 中定义 table 成员函数的位置

Where to define table member functions in Lua

据我了解,有多种方法可以将成员函数定义为Lua中的table。例如,以下两个看起来是等价的:

-- 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)。我找不到任何 objective 理由来说明为什么它应该更好。

确实,相反,似乎有理由至少在初始化 table 时前向声明函数变量,如下所示:

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

这样 Lua 从一开始就知道成员的存在并可以正确设置哈希,而将成员数量增加到现有 table 可能需要重新哈希(尽管我无法想象这实际上会成为一个明显的性能问题,除非你对大量的小 tables 执行此操作。对于来源比较:https://www.lua.org/gems/sample.pdf

那么在定义table本身的时候,有什么理由不直接定义成员函数呢?或者只是一些语法糖(function name() 语法和冒号)不可用的事实?

作为函数式编程的书呆子,我更喜欢方法 b,因为它一次性定义了 table,而不是为我们需要添加的每个方法都修改一次。您应该注意的一件事是某些方法可能会相互调用,使用本地方法比调用 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,
}

如果方法之间缺乏对称性令人烦恼,您可以将所有方法设为本地并将它们添加到 table 构造函数中,就像我刚刚对 myfunc.

所做的那样

Egor 提出了另一个重要观点(如果 table 是 class,则更相关):

Method a allows you to access variable table1 as upvalue from inside your functions. Method b doesn't allow this.

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

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,
}