为什么要用元表
目的:元表拓展了普通表的行为。可以更方便进行普通表的操作
- 定义两个表a ={},b = {},想对a、b进行加法计算,通过元表操作会更方便(也可通过for循环计算)。
如何设置元表
--1. 设置元表 setmetatable(mytable,mymetatable) ----
mytable = {"orange","banana"} --定义普通表
mymetatable = {} --定义元表
setmetatable(mytable,mymetatable) -- 把 mymetatable 设为 mytable 的元表
setmetatable(mytable,mymetatable)[1] --返回mytable的第一个元素“banana”
mytable = setmetatable({"orange","banana"},mymetatable) --也可以直接这样定义
--2. 返回元表 getmetatable(mytable) -----
getmetatable(mytable) -- 返回 它的mymetatable元表
__index 元方法(最常用的键)
*注意,所有的下划线都是两个
作用:当普通表没有该元素时
- 是否有元表(没有:返回nil)
- 判断元表有没有 __index 方法(没有:返回nil)
- __index 方法为 nil:则返回 nil;
- __index 方法是一个表:则重复 1、2、3(表中有元素,则返回;没有,则返回nil);
- __index 方法是一个函数:则返回该函数的返回值。
- 判断元表有没有 __index 方法(没有:返回nil)
举例
---__inde方法是一个表 ---
> other = { foo = 3 }
> t = setmetatable({}, { __index = other })
> t.foo // 表中有该元素,返回
3
> t.bar // 表中无该元素,返回nil
nil
---__inde方法是一个函数 ---
mytable = setmetatable({key1 = "value1"},
{
__index = function(mytable, key)
if key == "key2" then
return "metatablevalue"
else
return nil
end
end
})
print(mytable.key1) // 有key1,输出value1
print(mytable.key2) // 普通表没有key2,return "metatablevalue" ,输出metatablevalue
__newindex
作用:当修改的是新的索引时起作用(给表添加新的键值对)
当该索引在普通表里时,按照普通表的走;当该索引不在普通表里时,按照__newindex走
mytable = {"orange","banana"}
mymetatable =
{
__newindex = function(tab,key,value)
print("修改的key:"..key.."把key的值修改为:"..value)
rawset(mytable, key, "\""..value.."\"") -- 将元素加入表里.注意"\""
--如果不加这个,原普通表还是没改变
--如果换成mytable[key] = value,会一直陷入死循环
end
}
mytable = setmetatable(mytable,mymetatable)
mytable[1] = "apple" -- 输出结果 apple
mytable[4] = "grape" -- 输出结果 修改的key:4 把key的值修改为:grape
操作符
__addindex 实现连接两个表
--要合并的两个表
mytable = {1,2,3}
secondtable = {4,5,6}
--定义元表的方法
mytable = setmetatable(mytable, {
__add = function(mytable, newtable)
---找到mytable的最大长度
local mn = 0
for k, v in pairs(mytable) do
if mn < k then
mn = k
end
end
---一个个放入newtable的值
for k, v in pairs(newtable) do
mn = mn + 1
table.insert(mytable, mn, v)
end
return mytable
end
})
mytable = mytable + secondtable
for k,v in ipairs(mytable) do
print(k,v)
end
其他操作符类似
| _add | 对应的运算符 '+'. |
|---|---|
| __sub | 对应的运算符 '-'. |
| __mul | 对应的运算符 '*'. |
| __div | 对应的运算符 '/'. |
| __mod | 对应的运算符 '%'. |
| __unm | 对应的运算符 '-'. |
| __concat | 对应的运算符 '..'. |
| __eq | 对应的运算符 '=='. |
| __lt | 对应的运算符 '<'. |
| __le | 对应的运算符 '<='. |