元表:
- 改变表的行为(运算符重载/访问不存在的键值),
- 一类具有相同行为的表具有相同的元表
- 设置元表:setmetatable(表,元表)
- 获得元表:getmetatable(表),返回该表的元表
元方法(两个下划线开头):
- 可以是函数也可以是表
- 对应不同的行为有不同的元方法
算数运算符的元方法:
相加:__add 相减:__sub 相乘:__mul
相除:__div 求余:__mod 指数:__pow
复数:__unm
关系运算符:
等于: __eq ~= 变为 not ==
小于: __lt
小于等于: __le
tostring转换为字符串:__tostring
..字符串连接符:__concat
特殊的元方法:
__index:访问不存在的键值(访问)
- 函数:按照函数逻辑执行
- 表:
- 查找元素的__index对应的表t是否有该方法
- 如果t没有这个方法,继续查找t是否有__index元方法,继续1
function Vec2:__index(key)
return Vec2[key]
end
local tb = {}
function tb:getLength()
print("test")
end
Vec2.__index = tb
__newindex:给不存在的键值赋值时(更新)
function Vec2:__newindex(key,value)
error("不允许添加新键值")
end
Vec2.__newindex = Vec2
例子
v1+v2:
- 先检查v1是否有元表,检查元表中是否有对应的元方法(__add)
- 如果有,按照元方法逻辑执行
- 如果v1没有,同理查找v2
- 如果都没有,就报错
代码
local Vec2 = {x = 1, y = 2}
function Vec2:new(x,y)
local obj = {}
obj.x = x or 0
obj.y = y or 0
setmetatable(obj,self)
self.__index = self
return obj
end
function Vec2:__tostring()
return "x = " .. self.x .. ",y = " .. self.y
end
function Vec2:__add(other)
local obj = Vec2:new()
obj.x = self.x + other.x
obj.y = self.y + other.y
return obj
end
function Vec2:getLength()
return math.sqrt(self.x ^ 2 + self.y ^ 2)
end
local v1 = Vec2:new(3, 4)
print(v1:getLength())
v1.z = 20
print(v1.z)
local v2 = Vec2:new(3, 4)
local v3 = v1 + v2
print(v3)
local v4 = v3 + v2
print(v4)