print("************元表*****************")
print("************元表概念*****************")
--任何表变量都可以作为另一个表的元表
--任何表变量都可以有自己的元表
--当我们子表中进行一些特定操作时,会执行元表中的内容
print("************设置元表*****************")
meta={}
myTable={}
--设置元素函数
--设置第一个参数 子表
--第二个参数 元表(爸爸)
setmetatable(myTable,meta);
print("*********** 特定操作*****************")
print("************特点操作---tostring*****************")
---当子表被动作字符串使用时,会默认调用元表中的tostring方法
meta2={
__tostring=function ( ... )
-- body
return "原表"
end
}
myTable2=
{
}
setmetatable(myTable2,meta2);
print(myTable2);
--总结:调用myTabele2输出meta2中返回的内容:设置元表以后,调用子表,会调用到元表中的内容
-------带参
meta3={
__tostring=function ( t )
-- body
return t.name
end
}
myTable3=
{
name="子表";
}
setmetatable(myTable3,meta3);
print(myTable3);
--总结:元表中传递一个参数,会默认为子表
print("************特定操作---call*****************")
--当子表被当作一个函数使用时,会默认调用__call中的内容
--希望传参时,默认第一个参数时调用者自己
meta4={
__tostring=function ( t )
-- body
return t.name
end,
__call=function ( ... )
-- body
return "__call使用"
end
}
myTable4=
{
name="子表";
}
setmetatable(myTable4,meta4);
---把子表当作函数使用时,会调用元表中的__call中的内容
res=myTable4();
print(res);
--传参:第一个参数是调用者本身 也就是子表,第二参数才是传入的参数
print("************特定操作---运算符重载*****************")
meta5=
{
--运算符重载,当子表使用+运算符事,会执行该方法
__add=function(t1,t2 )
-- body
return t1.age+t2.age;
end,
--减
__sub=function ( t1,t2 )
-- body
return t2.age-t1.age;
end,
--乘
__mul=function ( t1,t2 )
-- body
return t2.age*t1.age;
end,
--除
__div=function ( t1,t2 )
-- body
return t2.age/t1.age;
end,
--求余
__mod=function ( t1,t2 )
-- body
return t2.age%t1.age;
end,
--幂运算
__pow=function ( t1,t2 )
-- body
return t2.age^t1.age;
end,
--等等于
__eq=function ( t1,t2 )
-- body
return t2.age==t1.age;
end,
--<
__lt=function ( t1,t2 )
-- body
return t2.age<t1.age;
end,
--<=
__le=function ( t1,t2 )
-- body
return t2.age<=t1.age;
end,
--拼接
__concat=function ( t1,t2 )
-- body
return t2.age..t1.age;
end,
}
myTable5={age=1}
myTable6={age=17}
setmetatable(myTable5,meta5);
setmetatable(myTable6,meta5);
print(myTable6+myTable5);
print(myTable5-myTable6);
print(myTable6*myTable5);
print(myTable5/myTable6);
print(myTable6%myTable5);
print(myTable5^myTable6);
--使用条件运算符,来比较两个对象,
--两个对象元表要一致并且都拥有原表,一个没有元表会报错 不一致 调用方法不同,答案可能出现错误
print(myTable5==myTable6);
print(myTable5<myTable6);
print(myTable5<=myTable6);
print(myTable5..myTable6);
print("************特定操作---index和newIndex*****************")
--__index 当子表中找不到某一个索引时,会从元表中的__index指定的表中去查找属性
meta7={};
myTable7={};
setmetatable(myTable7,meta7);
print(myTable7.age);--输出空
meta8={age=18};
meta8.__index=meta8
myTable8={};
setmetatable(myTable8,meta8);
print(myTable8.age);--输出18
meta9=
{
};
meta9.__index=meta9;
meta10=
{
};
meta10.__index={age=222}
myTable9={
};
setmetatable(meta9,meta10);
setmetatable(myTable9,meta9);
print(myTable9.age);--查找顺序:myTable9中查找 没有去找元表meta9中的__index指向的表,meta9中没有age,去meta9中的元表meat10中的__index指向的表中进行查找age
-----__newindex 当赋值时,子表中不存在会从元表的__newindex指向的表中查找属性进行赋值
meta11={};
myTable11={};
setmetatable(myTable11,meta11);
myTable11.age=1;
print(myTable11.age);--输出1
meta12={};
meta12.__newindex=meta12;
myTable12={};
setmetatable(myTable12,meta12);
myTable12.age=1;
print(myTable12.age);--输出nil
--getmetatable:获取元表
print( getmetatable(myTable12));
--rawget 绕开__index 从自身表中获取属性
--rawset 绕开__newindex 对自身表中进行赋值
注意:
__index 当子表中找不到某一个索引时,会从元表中的__index指定的表中去查找属性
__newindex 当赋值时,子表中不存在会从元表的__newindex指向的表中查找属性进行赋值