lua metatable 和 _index 实验
lua metatable 和 _index
中文博客解释:
http://www.cnblogs.com/simonw/archive/2007/01/17/622032.html
metatable:http://www.lua.org/pil/13.html
表的通用方法中,有些缺失的, 使用metatable可以定义表的这些默认方法:
add, sub, mul, div, mod, pow, unm, concat, len, eq, lt, le, tostring, gc, index, newindex, call...
__index: http://www.lua.org/pil/13.4.1.html
当访问表中无此元素, 则查询metatable中是否有__index, 如果有则获取_index调用结果, 如果没有__index则返回nil
__newindex : http://www.lua.org/pil/13.4.2.html
当设置表中不存在的key时候, 触发调用metatable 的 __newindex, 如果没有__newindex则设置到目标表的属性上, 如果存在__newindex, 则执行它。
例子:
__index __newindex 对比:
local Bird = {CanFly = true} function Bird:New() local b = {} setmetatable(b, self) self.__index = self --self.__newindex = self return b end local Ostrich = Bird:New() --Bird.CanFly is true, Ostrich.CanFly is true Ostrich.CanFly = false --Bird.CanFly is true, Ostrich.CanFly is false print("Ostrich.CanFly="..tostring(Ostrich.CanFly)) print("Bird.CanFly="..tostring(Bird.CanFly))
其他测试实验:
--定义2个表 a = {5, 6} b = {7, 8} --用c来做Metatable c = {} --重定义加法操作 c.__add = function(op1, op2) for _, item in ipairs(op2) do table.insert(op1, item) end return op1 end --自定义方法 c.print = function() print("c print!"); end --将a的Metatable设置为c, 报错,print为nil NOK --[[ setmetatable(a, c) a.print() ]] --将a的Metatable设置为c, 调用c定义的内置函数 OK --d现在的样子是{5,6,7,8} --[[ setmetatable(a, c) d = a + b for _, item in ipairs(d) do print(item) end ]] --将a的__index设置为c, 可以调用c定义的print OK --[[ setmetatable(a, {__index = c}) a.print() ]] --将a的metatable设置为c, 可以调用c定义的print OK --[[ c.__index = c setmetatable(a, c) a.print() --]] --将a的__index不能直接复制为c, 报错, NOK --[[ a.__index = c a.print() --]] --将a的__index设置为c, 报错a不能执行算出运算, NOK --[[ setmetatable(a, {__index = c}) d = a + b for _, item in ipairs(d) do print(item) end ]] --将a的__add设置为c的__add, OK --[[ setmetatable(a, {__add=c.__add}) d = a + b for _, item in ipairs(d) do print(item) end --]] -- 可以调用自定义方法, 和 内置方法 OK --[[ setmetatable(a, {__index = c, __add=c.__add}) a.print() d = a + b for _, item in ipairs(d) do print(item) end --]]
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。