Metatable In Lua 浅尝辄止
原文链接:http://www.cnblogs.com/simonw/archive/2007/01/17/622032.html 什么是Metatable? ??????Lua中Metatable这个概念,国内将他翻译为元表. 元表为重定义Lua中任意一个对象(值)的默认行为提供了一种公开入口. 如同许多OO语言的操作符重载或方法重载. Metatable能够为我们带来非常灵活的编程方式.? ??????具体的说,Lua中每种类型的值都有都有他的默认操作方式,如,数字可以做加减乘除等操作,字符串可以做连接操作,函数可以做调用操作,表可以做表项的取值赋值操作. 他们都遵循这些操作的默认逻辑执行,而这些操作可以通过Metatable来改变. 如,你可以定义2个表如何相加等.?
??????看一个最简单的例子,重定义了2个表的加法操作. 这个例子中将c的__add域改写后将a的Metatable设置为c,当执行到加法的操作时,Lua首先会检查a是否有Metatable并且Metatable中是否存在__add域,如果有则调用,否则将检查b的条件(和a相同),如果都没有则调用默认加法运算,而table没有定义默认加法运算,则会报错.
--定义2个表
a?=?{5,?6} b?=?{7,?8} --用c来做Metatable c?=?{} --重定义加法操作 c.__add?=?function(op1,?op2) ???for?_,?item?in?ipairs(op2)?do ??????table.insert(op1,?item) ???end ???return?op1 end --将a的Metatable设置为c setmetatable(a,?c) --d现在的样子是{5,6,7,8} d?=?a?+?b 有了个感性的认识后,我们看看Metatable的具体特性.
local?Bird?=?{CanFly?=?true}
function?Bird:New() ????local?b?=?{} ????setmetatable(b,?self) ????self.__index?=?self ????return?b end local?Ostrich?=?Bird:New()?--Bird.CanFly?is?true,?Ostrich.CanFly?is?true Ostrich.CanFly?=?false?--Bird.CanFly?is?true,?Ostrich.CanFly?is?false __newindex与__index相对应,在对table的key做更新时触发. 可以使用rawset和rawget对table的key操作来跳过这些事件的触发.? 调用与截获 ??????Java与C#中需要费不少周折来实现动态代理和AOP,类似这样的功能在Lua中确很简单,虽然被限制了很多,但你依然能够感受到Lua的灵活. 这就是__call操作,当值被调用时触发.? ??????这里我将table类型的a做了一个函数方式的调用a(),会触发__call. 另一个应用示例可以参见我的另一篇文章 Lua中实现类似C#的事件机制
a?=?{}
function?a:Func() ???print("simonw") end c?=?{} c.__call?=?function(t,?) ???print("Start") ???t.Func() ???print("End") end setmetatable(a,?c) a() --[[ Start simonw End ]] ??????这里的示例都是以最简单的方式展现,以便能更清晰的描述核心,更多的资料以及具体应用请参考Programming In Lua和Lua参考手册. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |