元表(metatable)
- Lua中每个值都有一个元表。table和userdata可以有各自独立的元表,而其他类型的值,则共享其类型所属的单一元表;
- 元表本身就是一个常规的表,任何人、任何函数都可以使用它们;
- 一个tabel可以作为自己的元表
- 在Lua中只能设置table的元表,其他类型的值的元表,必须通过C代码来完成;
- 新创建的表table没有元表;
两个很重要的函数:
-- 对指定表t设置元表mt,如果mt中存在 __metatable 键值,setmetatable 会失败。
setmetatable(t, mt)
-- 返回表t的元表mt。未设置元表时,返回nil
getmetatable(t)
__index
__index
:当访问table中不存在的索引key时,解释器会先查找该元方法。如果没有该方法,则返回nil;有则:
__index可以是一个函数,也可以是一个table。
- 函数:执行该函数
__index(t, k)
,并返回值 - 表table:在该表中访问原表中不存在的key
local t = {
x = 1, y = 2} -- 新表
print(t.z) -- 直接访问不存在的key,返回 nil
local mt = {
} -- 元表
mt.__index = {
z = 3} -- 元方法是一个表
setmetatable(t, mt)
print(t.z) -- 直接访问不存在的key,会查找元方法__index,最终返回 3
__newindex
__newindex
:当给table中不存在的索引key赋值时,解释器会先查找该元方法。若没有,则执行赋值操作;若有则不是执行赋值操作,而是:
__newindex可以是一个函数,也可以是一个table。
- 函数:执行该函数
__newindex(t, k, v)