<pre name="code" class="plain">--[[
lua元表完成
数值和逻辑运算
]]
--[[
Lua不支持函数默认值
所以通过是否为nil来判断
如果是nil的话,not nil为true
Lua支持的元表函数
__add 加
__sub 减
__div 除
__unm 负
__pow 幂
Lua支持的元表逻辑运算
__eq 等于
__lt 小于
__le 小于等于
]]
require("math")
function less(p1,p2)
len1=p1.d_getDist()
len2=p2.d_getDist()
if len1<len2 then
return true
end
return false
end
function equal(p1,p2)
if (p1._x == p2._x) and (p1._y==p2._y) then
return true
end
return false
end
function lessEqual(p1,p2)
len1=p1.d_getDist()
len2=p2.d_getDist()
if len1<=len2 then
return true
end
return false
end
function new_Point(x,y)
if not x then
x=0
end
if not y then
y=0
end
local Point={_x=x, _y=y}
Point.mt={}
setmetatable(Point,Point.mt)
function Point.add(p1,p2)
local ret=new_Point()
ret._x=p1._x+p2._y
ret._y=p1._y+p2._y
return ret
end
function Point.sub(p1,p2)
local ret=new_Point()
ret._x=p1._x-p2._x
ret._y=p1._y-p2._y
return ret
end
function Point.toString()
str="x=".. Point._x.." y=".. Point._y
return str
end
function Point.d_getDist()
--[[print("------------")
Point.toString()
print(Point._x,Point._y)]]
local v= math.sqrt(Point._x*Point._x + Point._y*Point._y)
--print("v="..v)
return v
end
--原来的设计,这么写每个Point对象都有自己的函数
--会导致无法比较,所以元方法最好是写成全局的外部函数
--[[
function Point.less(p1,p2)
len1=p1.d_getDist()
len2=p2.d_getDist()
if len1<len2 then
return true
end
return false
end
--错误做法
Point.mt.__lt=Point.less
]]
--需要先定义函数才能设置元函数
--如果放在setmetatable后
--也就是function Point.add前
--会设置失败,认为Point.add是nil
Point.mt.__add=Point.add
Point.mt.__sub=Point.sub
Point.mt.__tostring=Point.toString
--逻辑运算
Point.mt.__eq=equal
Point.mt.__lt=less
Point.mt.__le=lessEqual
return Point
end
do
--lua调用时如果不给参数则是nil
local p0 = new_Point()
--p0.toString()
print(getmetatable(p0))
local p1 = new_Point(10,20)
local p2 = new_Point(30,40)
print(p1)
print(p2)
local p3=p1+p2
print(p3)
local p4=p3-new_Point(20,20)
print(p4)
--[[
运行结果
table: 0072BA08
x=10 y=20
x=30 y=40
x=50 y=60
x=30 y=40
]]
local pp1=new_Point(3,4)
local pp2=new_Point(3,5)
local pp3=new_Point(3,4)
print("type(pp1)=",type(pp1))
print(pp1.mt.__lt)
print(pp1.mt.__eq)
print(pp1.mt.__le)
print(pp1.mt.__eq(pp1,pp2))
print(pp1.mt.__eq(pp1,pp3))
print(pp1.mt.__lt(pp1,pp3))
print("pp1==pp2",pp1==pp2)
print("pp1==pp3",pp1==pp3)
print("pp1<pp3",pp1<pp3)
print(pp1)
print(pp2)
pmt1=getmetatable(pp1)
print(pmt1.__lt)
pmt2=getmetatable(pp2)
print(pmt2.__lt)
--setmetatable(pp1,{['__lt']=pp1.less})
--setmetatable(pp2,{['__lt']=pp2.less})
print("compare table:",(pp1<pp2))
local cond=(pp1<pp2)
--boolean类型不能直接使用..来序列化
--print("cond="..cond)会报如下错误
--attempt to concatenate local 'cond' (a boolean value)
print("cond=",cond)
print("dist1=".. pp1.d_getDist())
print("dist3=".. pp3.d_getDist())
print(pp1==pp2)
print(pp1==pp3)
print(pp1<pp2)
print(pp1<=pp2)
end
lua-元表【实现类功能的核心】
最新推荐文章于 2021-07-02 16:38:20 发布