Lua中的元表和元方法

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”:^(取幂)操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值