lua学习笔记_metatable,__index,__newindex

--lua 的元表

--[[
	lua的元表允许我们改变table表的行为,例如我们可以通过修改元表实现两个共同元表的table的相加+
	当我么能用到两个相同的元表的table进行相加时他会去寻找元表的__add方法,通过这个方法来实现两个元表的相加
]]--

Set = {}		--声明一个table

Set.mt = {}		--声明这个table作为Set的metatable(元表)

--这个方法是元表相加方法的具体实现
function Set.union(a, b)
	local res = Set.new{}
	for i in pairs(a) do res[i] = a[i]  end
	for i in pairs(b) do res[i + #a] = b[i]  end
	return res
end

Set.mt.__add = Set.union	--将相加的方法添加进将要设置为metatable(元表)的table

--设置元表
--setmetatable(Set, Set.mt)	

--为了方便起见 我们设置用一个new方法 来做为Set的示例化,实例化后他们将共享一个元表
function Set.new(t)
		local res = {}
		for i in pairs(t) do
				res[i] = t[i] 
		end
		setmetatable(res, Set.mt) 				--设置元表
		return res
end


--使用

s1 = Set.new{10, 20, 30, 40, 50}
s2 = Set.new{60, 70, 80, 90, 100}

s3 = s1 + s2

for i in pairs(s3) do
	print(i, s3[i])
end



--[[
Lua选择metamethod的原则:如果第一个参数存在带有__add域的metatable,Lua使用它作为metamethod,和第二个参数无关
否则第二个参数存在带有__add域的metatable,Lua使用它作为 metamethod否则报错
 

元方法一般开头都会加两个下划线__
常用的关系运算元方法有以下几种
__add	加	+
__mul	乘	*
__sub	减	-
__div	除	/
__unm	负	-
__pow	幂	^
__mod		%		详细链接:http://www.cnblogs.com/colin-chan/articles/4774651.html
__concat	连接	详细链接:http://blog.csdn.net/LIQIANGEASTSUN/article/details/46592005
__eq	等于	==
__lt	小于	<
__le	小于等于 <=
a ~= b 表示为 not (a == b)



其他的一些metamethod

__tostring
__metatable getmetatable 将返回这个域的值 而调用setmetatable将会出错

表相关的 metamethods

__index	当我们访问一个表的不存在的域,返回结果为 nil,这是正确的,但并不一定正确。
		实际上,这种访问触发 lua 解释器去查找__index metamethod:如果不存在回结果为nil;
		如果存在则由__index metamethod 返回结果。__index的这种特性可以用做继承(详情见示例)

__newindex	metamethod 用来对表更新,__index 则用来对表访问。当你给表的一个缺少的域赋值,
			解释器就会查找__newindex metamethod:如果存在则调用这个函数而不进行赋值操作。

详细解释:
	__index详解:http://www.jb51.net/article/55152.htm
	__index和__newindex详解:http://www.jb51.net/article/55155.htm
]]--
--__index例子

Window = {}		--声明一个table

Window.prototype = {x = 0, y = 0, with = 100, height = 100,}	--table的一些默认属性  可能是窗口的大小等

Window.mt = {}		--窗口table的元表

--新建table方便  new方法 共享同一个metatable
function Window.new (o)		
	setmetatable(o, Window.mt)
	return o
end

--这个__index确定的当访问这个table时没有访问到响应的变量或者对象时来调用这个__index
--table是w	key是with
Window.mt.__index = function(table, key)
	for i in pairs(table) do
		print(i, table[i])
	end
	return Window.prototype[key]
end

--新建table时并没有初始化with 但是当去访问为nil 的时候就会去调用__index方法 读取这里的返回值
w = Window.new{x = 10, y = 20}

print(w.with)


你可能感兴趣的:(lua)