版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/codingriver/article/details/83020516
1)元表设置:setmetatable(table, metatable)
2)元表读取:getmetatable(table)
3)元方法操作:
metatable.元方法 = function (可接受参数)
(函数体)
end
如:
-- 定义__index元方法
Windows.mt.__index = function (table, key)
return Windows.default[key]
end
table访问的元方法
4)元方法:
算数运算符:__add(加法)[+]、__mul(乘法)[*]、__sub(减法)[-]、__div(除法)[/]、__unm(相反数)[-]、__mod(取模)[%]、__pow(乘幂)[^]。
逻辑运算符:__eq(等于)[=]、__lt(小于)[<]、__le(小于等于)[<=]。
其他运算符:__concat(连接)[…]、__len(取长度)[#]。
其他元方法:
__tostring:返回值(可接受参数:table)
__call:函数调用(可接受参数:table, key)
__metatable:保护元方法(字符串)
__index:查找表索引(可接受参数:table, key)
__newindex:添加新索引(可接受参数:table, key, value)
5)说明:
__add
如果任何不是数字的值(包括不能转换为数字的字符串)做加法, Lua 就会尝试调用元方法。 首先、Lua 检查第一个操作数(即使它是合法的), 如果这个操作数没有为 “__add” 事件定义元方法, Lua 就会接着检查第二个操作数。 一旦 Lua 找到了元方法, 它将把两个操作数作为参数传入元方法, 元方法的结果(调整为单个值)作为这个操作的结果。 如果找不到元方法,将抛出一个错误。(其它 算数运算符和逻辑运算符及其它运算符跟这个类似)
__index
当我们访问一个表的不存在的域,返回结果为nil,这是正确的,但并不一定正确。实际上,这种访问触发lua解释器去查找__index元方法:如果不存在,返回结果为nil;如果存在则由__index 元方法返回结果。当我们想不通过调用__index 元方法来访问一个表,我们可以使用rawget函数。Rawget(t,i)的调用以raw access方式访问表。这种访问方式不会使你的代码变快(the overhead of a function call kills any gain you could have),但有些时候我们需要他,在后面我们将会看到。
__newindex
__newindex元方法用来对表更新,__index则用来对表访问。当你给表的一个缺少的域赋值,解释器就会查找__newindex元方法:如果存在则调用这个函数而不进行赋值操作。像__index一样,如果元方法是一个表,解释器对指定的那个表,而不是原始的表进行赋值操作。另外,有一个raw函数可以绕过元方法:调用rawset(t,k,v)不掉用任何元方法对表t的k域赋值为v。__index和__newindex 元方法的混合使用提供了强大的结构:从只读表到面向对象编程的带有继承默认值的表。