在 lua 中添加表格

Adding tables in lua

如果我有一个看起来像 table1 = {x = 0, y = 0} 的 table 和另一个看起来像 table2 = {x = 0, y = 2} 的 table 我希望能够像这样添加它们

table1 += table2 --table1 now == {x = 0, y = 2}

等效的 C++ 代码如下所示:

typedef struct {int x; int y;} S;
S s1 = {0, 0};
S s2 = {0, 2};
int add(S ls1, S ls2)
{
    s1.x = s1.x + s2.x;
    s1.y = s1.y + s2.y;
    return s1.x;
}

int main() {
    add(s1, s2);
    std::cout << s1.x << " " << s1.y;
}

甚至更好

#include <iostream>



typedef struct {int x; int y;} S;
S s1 = {0, 0};
S s2 = {0, 2};
int operator+=(S ls1, S ls2)
{
    s1.x = s1.x + s2.x;
    s1.y = s1.y + s2.y;
    return s1.x;
}

int main() {
    s1 += s2;
    std::cout << s1.x << " " << s1.y;
}

如果您确保两个表具有相同的索引键,那么您可以简单地使用 _add 元方法来实现这一点:

local table1 = {x=0, y=2, z=3}
local table2 = {x=0,y=5}

local meta = {
    __add = function(t1, t2)
        local new = {}
        for i,v in pairs(t1) do
           if t2[i] then
             new[i] = t1[i] + t2[i]
           end
        end
   return new
end
}

setmetatable(table1,meta)
setmetatable(table2,meta)

for k, v in pairs(table1 + table2) do
    print(k, v)
end

只需迭代...

function add(t1,t2)
    local new = {}
    for i,v in pairs(t1) do
        if type(v) == "number" and type(t2[i]) == "number" then
            new[i] = v + t2[i]
        else
            new[i] = v
        end
    end
    return new
end

这里有两个选择:

像 warspyking 建议的那样简单地实现一个添加功能。

实现相同的功能并将其设置为表的 __add 元方法,类似于 Digital Veer 建议的方法。尽管为了方便起见,我会在这里定义一个对象,并且只根据需要添加 2 个组件 x 和 y。否则,您每次都必须手动为两个表设置元表。

Point = {}

function Point:New(x,y)

  local o = {}
  setmetatable(o, self)
  self.__index = self
  self.__add = function (p1,p2) return Point:New(p1.x + p2.x, p1.y + p2.y) end
  o.x = type(x) == "number" and x or 0
  o.y = type(y) == "number" and y or 0

  return o

end

然后你可以这样做:

local a = Point:New(1,1)
local b = Point:New(2,2)
local c = a + b

Lua 没有正式的 class 系统。您可以通过元表系统共享代码,其中包括 __index__tostring__add

您要求接线员 +=。 Lua 有一组固定的运算符。虽然,您可以为您的表定义它们,但您不能创建新的。所以,+= 出局了。作为,@Piglet ,您可以使用 _add 元方法定义 +。当然,+ 不会修改左操作数。虽然那样可能更好,但它不是您所建模的。

一个更像你建模的方法(但我会调用方法 "offset" 和参数 "delta")是这样的:

local S = {}
S.__index = S -- expose members of S to tables created by S:New

function S:New(x,y)
  return setmetatable({ x=x, y=y }, self)
end

function S:__tostring()
    return tostring(self.x) .. " " .. tostring(self.y)
end

function S:Offset(delta)
   self.x = self.x + delta.x
   self.y = self.y + delta.y
   return self
end

-- Example…

local s1 = S:New(0,0)
local s2 = S:New(1,2)
print(s1:Offset(s2))
print(s1)