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
--]]

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。