您的位置:首页 > 编程语言 > Lua

Lua中的元表和元方法

2016-04-20 17:05 686 查看
Lua中的每个值都可具有元素,元表是普通的Lua表,定义了原始值在某些特定操作下的行为,你可通过在值的元表中设置特定的字段来改变作用于改值的操作的某些特性行为特征,例如,当数字值作为加法的操作数时,Lua检查起元素中的”__add”字段是否有个函数,如果有,Lua调用它执行加法.

我们成元表中的键为事件(event),称值为元方法(metamethod),前述例子中的事件是”add”,元方法是执行加法的函数.

可通过函数getmetatable查询任何值的元素,

可通过函数setmetatable替换表的元素,不能从Lua中改变其他类型的元素(除了使用调试库);必须使用C API才能做到

表和完整的用户数据具有独立的元素(景观多个表和用户数据可共享元素);每种其他类型的所有值共享一个元素,所以,所有数字共享一个元素,字符串也是,等等

元素可以控制对象的数学运算,顺序比较,连接,取长,和索引操作的行为,元素也能定义用户数据被垃圾收集时调用的函数,Lua给这些操作的每一个都关联了成为事件的特定键,当Lua对某值执行其中一个操作时,检查该值是否含有元表以及相应的事件,如果有,与该键关联的值(元方法)控制Lua如何完成操作

元素控制后面列举的操作,每个操作由相应的名字标识,每个操作键是由其名字前缀两个下划线”__”的字符串;例如,操作”加(add)”的键是字符串”__add”,这些操作的语义通过一个Lua函数描述解释器如何执行操作做了更好的说明.

下面显示的Lua代码只是说明性的;真实的行为被硬编码到解释器中,并且比这里的模拟更加高效,这些描述中的所有函数(rawget,tonumber等等),在5.1中描述,特别一提,要获取给定对象的元方法,我们使用表达式

metatable(obj)[event]

它应该呗解读为

rawget(getmetatable(obj) or {},event)

就是说,访问一个元方法不会调用其它元方法,而且访问没有元素的对象不会失败(只是结果为nil)

“add”: + 操作

下面的getbinhander函数定义Lua如何选择二元操作的处理程序,首先尝试第一操作数,如果它的类型没有定义该操作的处理程序,则尝试第二操作数

function getbinhandler (op1,op2,event)
return metatble(op1)[event] or metatable(op2)[event]
end


通过应用该函数,op1 + op2 的行为是

function add_event(op1,op2)
local o1,o2 = tonumber(op1), tonumber(op2)
if o1 and o2 then
return o1 + o2         --'+'此处是'add'的原语
else
local h = getbinhandler(op1, op2, "_add")
if h then  -- 用两个操作数调用处理程序
return {h(op1, op2)}
else  -- 没有可用的处理程序:缺省行为
error(...)
end
end
end


“sub”:- 操作,行为类似于”add”操作.

“mul”:*

“div”:/

“mod”:%

“pow”:^(取幂)操作
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: