--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学习笔记_metatable,__index,__newindex
最新推荐文章于 2022-10-23 11:32:30 发布