一:什么是元表

元表是经过普通表扩展的表,使得扩展一些功能更加方便
在Lua中我们可以访问到表的键和值,然后对他们进行操作,但是无法对两个表直接进行操作,假如我们想直接对两个表进行相加,使用元表可以拓展功能


二:设置元表

setmetatable返回值为普通表
Lua(十四)——元表_Lua 热更新

两种设置的方法:
Lua(十四)——元表_热更新_02


三:得到元表

getmetatable返回值为元表
Lua(十四)——元表_Lua 热更新_03


四:元方法

元方法就是元表中的键

——__index
1.当__index对应一个函数
函数参数是与元表相关联的普通表和不存在的键。当访问了一个不存在的键(索引)时,就会调用__index对应的方法
这个函数默认有一个返回值,如果我们不定义这个返回值,当访问了一个不存在的键(索引)时,它默认返回nil
Lua(十四)——元表_Lua 热更新_04     Lua(十四)——元表_Lua 热更新_05
2.当__index对应一个表
当访问了一个不存在的键(索引)时,就会去__index对应的表中去找,如果__index对应的表中有此元素,则返回此元素的值,如果__index对应的表中也没有此元素,则返回nil
Lua(十四)——元表_热更新_06

 

 

——__newindex
1.当__newindex对应一个函数
函数参数是与元表相关联的普通表,新添的键和新添的值
当添加新的键值对时(不是修改原有的键和值),就会调用__newindex对应的函数
Lua(十四)——元表_热更新_07
2.如果__newindex对应一个表
当添加新的键值对时(不是修改原有的键和值),就会给__newindex对应的表赋值
Lua(十四)——元表_Lua 热更新_08

当添加新的键值对时(不是修改原有的键和值),就会调用__newindex对应的函数,但是不会进行赋值,输出table[4]发现table[4]仍然为nil,表中并没有添加此元素
Lua(十四)——元表_热更新_09
因为当程序发现我们要添加新的键值对时,就去调用__newindex对应的方法,此方法并没有添加元素到table中,所以想让元素添加到元表中,还需写一步添加元素的操作,首先想到的就是如下写法,但是发现报错,原因是key是一个不存在的键,相当于添加新的数据,所以一直在调用元方法__newindex中的tab[key]=value语句,形成了溢出
Lua(十四)——元表_Lua 热更新_10
Lua提供了一个更新表中元素的内置函数:rawset
 Lua(十四)——元表_热更新_11

 

 

 

——__add
当表中元素相加时,就会调用元表中的__add方法
__add对应的是一个函数,函数参数是相操作的表1和表2
Lua(十四)——元表_热更新_12      Lua(十四)——元表_热更新_13

 

 

 

——__call
当把表当作函数使用时,就会调用元表中的__call方法
__call键对应的值是一个函数,函数参数是与元表相关联的普通表和函数参数(参数可以为普通类型也可以为可变参数)Lua(十四)——元表_热更新_14

 

 

 

——__tostring
当把表作为字符串输出时(使用print),就会调用元表中的__tostring方法
__tostring键对应的值是一个函数,函数参数是与元表相关联的普通表
这个函数必须有一个返回值当做字符串去输出
Lua(十四)——元表_Lua 热更新_15


五:__metatable键值的作用

使用__metatable可以保护元表,禁止用户访问和修改
如果元表中有__metatable的键存在则getmetatable时只会输出__metatable的值,起到了保护作用
Lua(十四)——元表_热更新_16