--元表,元表附属于表,用于表的扩展,是更底层的东西。
--元表的作用多种多样,其中一个就是可以在对普通表操作时方法的重载,用于扩展,因此一般情况下定义好后不需要再次修改元表。
----比如让两个表进行相加,如果没有元表的话直接相加编译器会报错的。
----还有就是用print输出表时,是直接输出这个表的内存块名,用了元表就可以很方便的输出表的元素
tab1 = {1,2,3,4,5,6}
met1 = {}
tab2 = setmetatable(tab1,met1)
met2 = getmetatable(tab1)
print(tab1,tab2) --输出:table: 00A395A0 table: 00A395A0
print(met1,met2) --输出:table: 00A39A50 table: 00A39A50
----------------------------------------------------
-- __metatable关键字,可以保护元表,禁止用户访问元表中的成员或者修改元表。
tab = setmetatable({"Lua","Java","C#","C++"} , {__metatable="lock"} )
print(getmetatable(tab)) --输出:lock
---------------------------------------------------------
--__index关键字,用于访问普通表不存在的Key时,所调用元表的扩展方法
tab1 = {1,2,3,4,5,6}
met1 = {
__index = function(tab,key)
print("tab",tab)
print("调用了元表的__index方法")
table.insert(tab1,key) --table表插入方法,参数1:table,参数2:[index]位置,参数3:value
end}
tab2 = setmetatable(tab1,met1)
met2 = getmetatable(tab1)
function OnContainTab(tab,value)
for k,v in pairs(tab) do
if v == value then
print("搜索到目标 k:"..k.." v:"..v)
return true
end
end
return false
end
print("tab1",tab1) --输出:tab1 table: 00B196D0
print("表的个数为: "..table.getn(tab1)) --输出:表的个数为: 6
print(tab1[100]) --输出:tab table: 00B196D0 | 调用了元表的__index方法 | nil
print("表的个数为: "..table.getn(tab1)) --输出:表的个数为: 7
OnContainTab(tab1,100) --输出: 搜索到目标 k:7 v:100
---------------------------------------------------------------
-- __newindex关键字,在table添加新的数据时,会调用这个
tab1 = {1,2,3,4,5,6}
local met1 = {
__newindex = function(tab,key,value) --元表关键字支持函数
print("普通表中未找到Key:"..key)
rawset(tab,key,value) --添加新的键值对
--table.insert(tab,key,value) --添加新的键值对
end
}
function OnContainTab(tab,value)
for k,v in pairs(tab) do
if v == value then
print("搜索到目标 k:"..k.." v:"..v)
return true
end
if k == value then
print("搜索到目标 k:"..k.." v:"..v)
return true
end
end
return false
end
newtab1 = setmetatable(tab1,met1)
newtab1[7] = "qi" --输出:普通表中未找到Key:7
OnContainTab(newtab1,7) --输出:搜索到目标 k:7 v:qi
tab2 = {1,2,3,4,5,6}
tab3 = {}
local met2 = {
__newindex = tab3 --元表关键字还支持Table
}
newtab2 = setmetatable(tab2,met2)
newtab2[7] = "qi" --由于元表__newindex指向了tab3,因此当普通表tab2的索引查不到Key时,会自动地赋值给tab3
print(tab2[7]) --输出:nil
print(tab3[7]) --输出:qi
---------------------------------------------------
-- add关键字,在table进行数学操作符时,进行扩展
tab1 = {1,3,5}
tab2 = {2,4,6}
local met1 = {
__add = function(tab_1,tab_2) --add关键字,参数1:tab1,参数2:tab2
for k,v in pairs(tab_2)do
table.insert(tab_1,v)
end
return tab_1
end
}
newtab1 = setmetatable(tab1,met1)
tab3 = tab1+tab2
for k,v in pairs(tab3) do
print(k,v) --输出:1 1 | 2 3 | 3 5 | 4 2 | 5 4
end
----------------------------------------------------
-- __call关键字,可把table当做函数来使用
tab1 = {1,3,5}
local met1 = {
__call =
function(tab,...) 使用"...",用于处理所有参数
print(...)
return tab
end
}
newtab1 = setmetatable(tab1,met1)
newtab1(123,123123) --输出:123 123123
------------------------------------------------------
-- __tosting关键字,用于直接打印table时,所扩展的方法
tab1 = {"一","二","三"}
local met1 = {
__tostring =
function(tab)
local string = ""
for k,v in pairs(tab) do
string = string..k.." "..v.."|"
end
return string
end
}
newtab1 = setmetatable(tab1,met1)
print(newtab1) --元表没有__tostring关键字则输出:table: 00DB9438,加了则输出:1 一|2 二|3 三|
Lua_Metatable元表
猜你喜欢
转载自blog.csdn.net/Le_Sam/article/details/85201429
今日推荐
周排行