元表

tableA = {"lua","java","c++"}
tableB = {"PHP","lua"}
tableA = setmetatable(tableA,tableB);--设置tableB为tableA的元表,返回的为普通表
for k,v in pairs(getmetatable(tableA)) do
  print(k,v);
end
print(setmetatable(tableA,tableB))
--元表扩展了普通表的行为
注意:
  setmetatable(table,metatable): 对指定 table 设置元表(metatable),如果元表(metatable)中存在 __metatable 键值,setmetatable 会失败。
  getmetatable(table): 返回对象的元表(metatable)。如果在元表中有__metatable的键值对,则直接返回__metatable对应的值
  __metatable在元表中可以保护元表,禁止用户访问元表中的成员或修改元表

__index:
  情况1、后面为一个方法
    如果__index包含一个函数的话,Lua就会调用那个函数,table和键会作为参数传递给函数。
    __index 元方法查看表中元素是否存在,如果不存在,返回结果为 nil;如果存在则由 __index 返回结果。
    mytable = {"lua","c#","java"};
    mymetatable = { __index = function(tab,key)--有两个参数
      print("调用__index");
      return 3
    end
    }
    mytable = setmetatable(mytable,mymetatable);
    print(mytable[4])--打印为3

  情况2:后面为一个表,当表中没有这个索引对应的值的时候,会在__index的表中进行查询
    mytable = {"lua","c#","java"};
    newtable = {};
    newtable[4] = "PHP";
    mymetatable = { __index =newtable};
      mytable = setmetatable(mytable,mymetatable);
      print(mytable[4])--打印为PHP
__newindex:
  后面也可以跟上一个表或一个函数;
  当对表中数据添加新的键值对的时候会调用__newindex
  __newindex= function(tab,key,value)
  rawset(mytable, key,value)//更新这个表

  mytable = {"lua","c#","java"};
  newtable = {};
  newtable[4] = "PHP";
  mymetatable = { __newindex =newtable};
当添加数据的时候,不会把数据添加到mytable表中,而是会把数据添加到__newindex的表中

__add:
  --给表定义加法操作
  __add = function(tableA,tableB)
  tableA+tableB的时候调用,只需要设置一个表的元表就可以了

其余操作符类似
__call:
  当把表当成一个函数来使用的时候调用
  tableA(tableB);--这个时候
  __call = function(tab,arg);
__tostring:
  __tostring = function(tab)
  print(tableA);--这个时候调用

原文地址:https://www.cnblogs.com/xingyunge/p/10936267.html