一:什么是元表
元表是经过普通表扩展的表,使得扩展一些功能更加方便
在Lua中我们可以访问到表的键和值,然后对他们进行操作,但是无法对两个表直接进行操作,假如我们想直接对两个表进行相加,使用元表可以拓展功能
二:设置元表
setmetatable返回值为普通表
两种设置的方法:
三:得到元表
getmetatable返回值为元表
四:元方法
元方法就是元表中的键
——__index
1.当__index对应一个函数
函数参数是与元表相关联的普通表和不存在的键。当访问了一个不存在的键(索引)时,就会调用__index对应的方法
这个函数默认有一个返回值,如果我们不定义这个返回值,当访问了一个不存在的键(索引)时,它默认返回nil
2.当__index对应一个表
当访问了一个不存在的键(索引)时,就会去__index对应的表中去找,如果__index对应的表中有此元素,则返回此元素的值,如果__index对应的表中也没有此元素,则返回nil
——__newindex
1.当__newindex对应一个函数
函数参数是与元表相关联的普通表,新添的键和新添的值
当添加新的键值对时(不是修改原有的键和值),就会调用__newindex对应的函数
2.如果__newindex对应一个表
当添加新的键值对时(不是修改原有的键和值),就会给__newindex对应的表赋值
当添加新的键值对时(不是修改原有的键和值),就会调用__newindex对应的函数,但是不会进行赋值,输出table[4]发现table[4]仍然为nil,表中并没有添加此元素
因为当程序发现我们要添加新的键值对时,就去调用__newindex对应的方法,此方法并没有添加元素到table中,所以想让元素添加到元表中,还需写一步添加元素的操作,首先想到的就是如下写法,但是发现报错,原因是key是一个不存在的键,相当于添加新的数据,所以一直在调用元方法__newindex中的tab[key]=value语句,形成了溢出
Lua提供了一个更新表中元素的内置函数:rawset
——__add
当表中元素相加时,就会调用元表中的__add方法
__add对应的是一个函数,函数参数是相操作的表1和表2
——__call
当把表当作函数使用时,就会调用元表中的__call方法
__call键对应的值是一个函数,函数参数是与元表相关联的普通表和函数参数(参数可以为普通类型也可以为可变参数)
——__tostring
当把表作为字符串输出时(使用print),就会调用元表中的__tostring方法
__tostring键对应的值是一个函数,函数参数是与元表相关联的普通表
这个函数必须有一个返回值当做字符串去输出
五:__metatable键值的作用
使用__metatable可以保护元表,禁止用户访问和修改
如果元表中有__metatable的键存在则getmetatable时只会输出__metatable的值,起到了保护作用