这个是lua中需要理解的概念,以前写过关于元表的笔记,好久没摸,又忘了。
元表概念 ( Metatable)
元表由键名为 事件 (event) 和其中的值叫作元方法 (metamethod)组成。
在lua中每个值都有一个元表。而table和userdata所定义的值允许自定义对应的元表,
其他都是用统一的元表。
我的理解,元表,其实有点类似值的属性的味道。
对元表的操作
getmetable 查询元方法
setmetable 替换元方法。
metatable 包含几个固定的元方法.
其事件名由下划线 '__' 前缀的字符串组成。
有
"add": + 操作。
"sub": - 操作。 其行为类似于 "add" 操作。
"mul": * 操作。 其行为类似于 "add" 操作。
"div": / 操作。 其行为类似于 "add" 操作。
"mod": % 操作。 其行为类似于 "add" 操作,它的原生操作是这样的 o1 - floor(o1/o2)*o2
"pow": ^ (幂)操作。 其行为类似于 "add" 操作,它的原生操作是调用 pow 函数(通过 C math 库)。
"unm": 一元 - 操作。
"concat": .. (连接)操作,
"len": # 操作。
"eq": == 操作。
a ~= b 等价于 not (a == b) 。
"lt": < 操作。
"le": <= 操作。
a >= b 等价于 b <= a 。注意,如果元方法 "le" 没有提供,Lua 就尝试 "lt" ,它假定 a <= b 等价于 not (b < a)
"index": 取下标操作用于访问 table[key] 。
"newindex": 赋值给指定下标 table[key]= value 。
"call": 当 Lua 调用一个值时调用。
以上事件中,index 和newindex 很关键,常常被自定义的函数所取代。
如:定义一个函数取代环境中的处理
local f = function (t,i)
error("cannot redefine global variable `"..i.."'",2)
end
local g = {}
local G = getfenv()
setmetatable(g,{__index=G,__newindex=f})
--设置g的运行环境
setfenv(1,g)
rawset(g,"x",3)
x=2
y=1 -- cannot redefine 'y'
以上的替换只能在C下改变,在lua中不能中改变其它任何类型的值的 metatable(debug 库例外);
值得说明的是:
table 和userdata类型拥有独立的 metatable (也可以共享一个相同的表作它们的 metatable)
在lua的扩展库函数中有一个
luaL_newmetatable
这个函数是创建一个表,作为元表提供给userdata使用。
(userdata,可以理解为自定义的一个数据结构。)