在 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)
如果我有一个看起来像 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)