Lua表的添加操作

假设我有一个表,其形式为 table1 = {x = 0, y = 0},还有一个形式为 table2 = {x = 0, y = 2} 的另一个表,我想要能够这样添加它们

table1 += table2 --现在table1等于{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;
}
点赞
用户3924687
用户3924687

如果确保两个表具有相同的索引键,则可以使用 _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
2016-03-26 03:04:29
用户3979429
用户3979429

只需迭代......

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
2016-03-26 05:01:44
用户2858170
用户2858170

你有两个选择:

  • 简单地实现一个像 warspyking 建议的 add 函数。
  • 或者,像 Digital Veer 建议的那样,将相同的函数实现并将其设置为表的 __add 元方法。尽管在实现中我会定义一个对象以方便操作,并且只添加你希望添加的两个分量 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
2016-03-26 09:35:37
用户2226988
用户2226988

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

您要求一个运算符 +=。Lua 有一组固定的运算符。虽然您可以为自己的表定义它们,但您不能创建新的运算符。因此,+= 不行。正如 @Piglet 所示,您可以使用 _add 元方法来定义 +。当然,+ 不会修改左操作数。虽然这可能更好,但这并不是您建模的方式。

更像您建模的方法(但我将该方法称为“偏移”方法,参数为“增量”)如下:

local S = {}
S.__index = S -- 暴露在 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

-- 示例...

local s1 = S:New(0,0)
local s2 = S:New(1,2)
print(s1:Offset(s2))
print(s1)
2016-03-26 15:59:41