Lua教程(九):元表与元方法详解
Lua中提供的元表是用于帮助Lua数据变量完成某些非预定义功能的个性化行为,如两个table的相加。假设a和b都是table,通过元表可以定义如何计算表达式a+b。当Lua试图将两个table相加时,它会先检查两者之一是否有元表,然后检查该元表中是否存在__add字段,如果有,就调用该字段对应的值。这个值就是所谓的“元方法”,这个函数用于计算table的和。
Lua中每个值都有一个元表。table和userdata可以有各自独立的元表,而其它数据类型的值则共享其类型所属的单一元表。缺省情况下,table在创建时没有元表,如:
t={} print(getmetatable(t)) --输出为nil
这里我们可以使用setmetatable函数来设置或修改任何table的元表。
t1={} setmetatable(t,t1) assert(getmetatable(t)==t1)
任何table都可以作为任何值的元表,而一组相关的table也可以共享一个通用的元表,此元表将描述了它们共同的行为。一个table甚至可以作为它自己的元表,用于描述其特有的行为。在Lua代码中,只能设置table的元表,若要设置其它类型值的元表,则必须通过C代码来完成。
1.算术类的元方法:
在下面的示例代码中,将用table来表示集合,并且有一些函数用来计算集合的并集和交集等。
Set={} localmetatable={}--元表
--根据参数列表中的值创建一个新的集合 functionSet.new(l) localset={} --将所有由该方法创建的集合的元表都指定到metatable setmetatable(set,metatable) for_,vinipairs(l)do set[v]=true end returnset end
--取两个集合并集的函数 functionSet.union(a,b) localres=Set.new{} forkinpairs(a)do res[k]=true end forkinpairs(b)do res[k]=true end returnres end
--取两个集合交集的函数 functionSet.intersection(a,b) localres=Set.new{} forkinpairs(a)do res[k]=b[k] end returnres end
functionSet.tostring(set) locall={} foreinpairs(set)do l[#l+1]=e end return"{"..table.concat(l,",").."}"; end
functionSet.print(s) print(Set.tostring(s)) end
--最后将元方法加入到元表中,这样当两个由Set.new方法创建出来的集合进行 --加运算时,将被重定向到Set.union方法,乘法运算将被重定向到Set.intersection metatable.__add=Set.union metatable.__mul=Set.intersection
--下面为测试代码 s1=Set.new{10,20,30,50} s2=Set.new{30,1} s3=s1+s2 Set.print(s3) Set.print(s3*s1)
--输出结果为: --{1,30,10,50,20} --{30,10,50,20}