【lua】元表

痞子三分冷 提交于 2019-12-17 00:32:05

lua元表
–当lua试图去对两个表相加时,先检查两个表之一是否有元表,之后再检查是否有一个叫“__add”的字段,若找到,则调用对应得值,如果找不到就返回nil,其中__add为即时字段,其对应的值(一般是函数或者是一个表)就是“元方法”
–处理元表的两个函数:
setmetatable(table,metatable):对指定的table设置元表(metatable),如果元表(metatable)中存在__metatable的键值,settatable会失败
getmetatable(table):返回对象的元表(metatable)

mytable={} --普通表
mymetatable={} --元表
setmetatable(mytable,mymetatable) --把mymetatable设为mytable的元表
也可以写成:
mytable=setmetatable({},{})
getmetatable(mytable) --这里是返回mytable的元表(mymetatable)

__index元方法,这是metatable最常用的键
–当通过键去访问table的时候,如果这个键没有值,就会去寻找该表的metatable(假定有metatable)中的__index键
如果__index包含的一个表,就会在这个表里面查找相对应的值
tab={a=3}
t=setmetatable({},{__index=tab})
–print(t.a)
–print(t.b)
如果__index包含一个函数的话,lua就会调用那个函数,table和键会作为参数传递给函数__index元方法会去查看表中的元素是否存在,如果不存在,
–则返回结果为nil,如果存在则由__index返回结果
mytable=setmetatable({key1=“value1”},{
  __index=function (mytable,key1)
   if key1 ==“key2” then
    return “metatablevalue”
   else
    return 1
   end
  end
})
print(mytable.key1)
print(mytable.key2)
print(mytable.key3)

–1.mytable表赋值为{key1=“value1”}
–2.mytable设置了元表,元方法为__index
–3.在mytable表中查找key1,如果找到了返回该元素,找不到则继续
–4.在mytable表中查找key2,如果找到则返回该元素,找不到继续
–5.继续去判断元表中有没有__index方法,如果__index是一个函数。则调用该函数
–6.元方法中查看是否传入"key2"键的参数(mytable.key2已设置),如果传入"key2"参数返回“metatablevalue”,否则返回mytable对应得键值

mytable=setmetatable({key1=“value1”},{
  __index={key2=“metatablevalue”}
})
print(mytable.key1)
print(mytable.key2)

总结:lua在查找一个表元素的时候,
 1.在表中查找,如果找到就返回该元素,找不到就继续
 2.判断该表是否有元表,如果没有元表,则返回nil,如果有元表则继续
 3.判断元表有没有__index方法,如果__index方法为nil的时候则返回nil,如果__index方法是一个表,则重复1,2,3步骤;如果__index方法是一个函数,则返回该函数的返回值
 
 
__newindex:用来对表更新,__index用来对表访问
–当我们给表的一个缺少的索引赋值的时候,lua解释器就会查找__newindex元方法,如果存在则调用这个函数而不进行赋值操作
mymetatable={}
mytable=setmetatable({key1=“value1”},{
  __newindex=mymetatable
})
print(mytable.key1) --value1

mytable.newkey=“新值2”
print(mytable.newkey,mymetatable.newkey) --nil 新值2

mytable.key1=“新值1”
print(mytable.key1,mymetatable.key1) --新值1 nil

for k,v in pairs(mymetatable) do
  print(“mymetatable”,k,v)
end

–设置了元方法__newindex,在对新索引建(newkey)赋值时(mytable.newkey=“新值2”)会调用元方法,而不进行赋值,而如果对已经存在的索引键(key)则会进行赋值,而不调用元方法__newindex
 
 
–table.maxn(table):在lua5.2版本已经弃用了
function calTable(table)
  local count = 0
  for k,v in pairs(table) do
   count=count+1
  end
  return count
end
__add:两表相加
mytable=setmetatable({1,2,3},{
  __add=function ( mytable1,newtable1)
   for i=1, calTable(newtable1) do
    table.insert(mytable1,newtable1[i])
   end
   return mytable1
end
})
secondTable={4,5,6}
mytable=mytable+secondTable
for k,v in pairs(mytable) do
  print(k,v)
end

–__add:对应得运算符"+"
–__sub:对应得运算符"-":减号
–__mul:对应得运算符"*"
–__div:对应得运算符"/"
–__mod:对应得运算符"%"
–__unm:对应得运算符"-":负号
–__concat:对应得运算符"…"
–__eq:对应得运算符"= ="
–__lt:对应得运算符"<"
–__le:对应得运算符"<="
 
 
__call:表 函数调用时
mytable=setmetatable({10},{
  __call=function (mytable1,newtable1)
   local sum =0
   for i=1,calTable(mytable1) do
    sum=sum+mytable1[i]
    end
   for i=1,calTable(newtable1) do
    sum=sum+newtable1[i]
   end
   return sum
  end
})
newtable={10,20,30}
print(mytable(newtable))
 
 
__tostring:用于修改表的输出行为
mytable=setmetatable({10,20,30},{
  __tostring=function ( mytable )
    local sum = 0
    for k,v in pairs(mytable) do
     sum=sum+v
    end
    return “表中的所有元素和为:”…sum
 end
})
print(mytable[1])

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!