lua中的metatable和metamethod

--元表和元方法给lua里的值设定一些操作,让我们可以对这些操作自定义
--创建一个新的table变量时,它是不存在元表的
--在Lua中,只能设置table的元表,其他类型的值的元表,只能通过C代码来完成
local mt={}
mt.__add=function(t1,t2)print("i am result")end
local t1={}
local t2={}
setmetatable(t1,mt)
setmetatable(t2,mt)
local result=t1+t2

 

a={numerator=2,denominator=3}
b={numerator=4,denominator=7}

op={}--metatable
function op.__add(f1,f2)
    ret={}
    ret.numerator=f1.numerator*f2.denominator+f1.denominator*f2.numerator
    ret.denominator=f1.denominator*f2.denominator
    return ret
end

setmetatable(a,op)
setmetatable(b,op)

s=a+b
print(s.numerator,s.denominator)--26,21

Metatable允许我们改变table的行为,例如,使用Metatables 我们可以定义Lua 如何计算两个table 的相加操作a+b。当Lua 试图对两个表进行相加时,他会检查两个表是否有一个表有Metatable,并且检查Metatable 是否有__add 域。如果找到则调用这个__add函数(所谓的Metamethod)去计算结果。

可以使用setmetatable函数设置或者改变一个表的metatable.

任何一个表都可以是其他一个表的metatable,一组相关的表可以共享一个metatable,一个表也可以是自身的metatable。

--模拟集合运算
--定义+来执行两个集合的并操作
Set={}
Set.mt={} --metatable for sets
function Set.new(t)
    local set={}
    setmetatable(set,Set.mt)
    for _,l in pairs(t) do
        set[l]=true
    end
    return set
end

function Set.union(a,b)
    local res=Set.new()
    for k in pairs(a) do res[k]=true end
    for k in pairs(b) do res[k]=true end
    return res
end

function Set.intersection(a,b)
    local res=Set.new()
    for k in pairs(a) do
        res[k]=b[k]
    end
    return res
end

function Set.tostring(set)
    local s="{"
    local sep=""
    for e in pairs(set) do
        s=s..sep..e
        sep=","
    end
    return s.."}"
end

function Set.print(s)
    print(Set.tostring(s))
end

Set.mt.__add=Set.union

s1=Set.new({10,20,30,50})
s2=Set.new({30,1})
s3=s1+s2--这行出错,原因不清楚
--the __index metamethod
Window={}
Window.prototype={x=0,y=0,width=100,height=100,}
Window.mt={}--metatable
function Window.new(o)
    setmetatable(o,Window.mt)
    return o
end

Window.mt.__index=Window.prototype
w=Window.new{x=10,y=20}
print(w.width)

 

posted @ 2015-04-24 15:50  合唱团abc  阅读(249)  评论(0编辑  收藏  举报