lua-元表【实现类功能的核心】

<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



                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值