lua学习笔记day10-----metatables and metamethods的算数运算

metatables:有点类似C++中的父类,当对tables进行一些操作时,会去到它的metatables中找相应的域来实现。metatables是一个普通的表,任何一个表都可以成为另一个表的metatables,也可以是自己的metatables。
metamethods:metatables中的域。lua中有一些核心的metamethods,一旦在使用tables的时候满足触发条件,就会跑到metatables中去调用。

lua中支持tables中的域进行算数运算,但是如果想要对tables进行算数运算就需要两张表至少有一张的metatables中包含算数运算相关的域。
“+” -> _add; “-” -> _sub; “*” -> _mul; “/” -> _div; “-” -> _unm; “” ->_pow(幂);
先了解一下这个触发关系。
当两张表相加的时候会先到第一张表的metatables中寻找是否有_add的域,如果有就按照第一张表的metatables运行,如果没有就在第二张表中寻找,如果还是没有就报错。
我们通过以下这个例子来深入了解。

Set = {}
Set.mt = {}
function Set.New(t)
        local set = {}
        setmetatable(set,Set.mt)
        for _,i in ipairs(t) do set[i] = 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 k in pairs(set) do
                s = s..sep..k
                sep = ", "
        end
        s = s.."}"
        return s
end
function Set.print(set)
        print(Set.tostring(set))
end
do
        Set.mt.__add = Set.union
        Set.mt.__mul = Set.intersection
        s1 = Set.New{10,20,30,40}
        s2 = Set.New{1,2,10,20}
        --[[s = s1 + s2--]]
        Set.print(s1 * s2)
end

先声明一个Set表用于存放我们所有的内容。
在Set表中声明一个mt的表用于当作其他表的metatable
Set.New(t),构造器,用于生成一个新的表,这个表的metatable是Set.mt
Set.union(a,b),用于对两个表做合集的操作
Set.intersection(a,b),用于对两个表做交集的操作
Set.tostring(set) 和 Set.print是用于打印表的。
然后将合集的操作定义成metatable中相加的操作,
将交集的操作定义成metatable中相乘的操作,如下:
将Set.mt.__add 指向 Set.union
将Set.mt.__mul 指向 Set.intersection
最后,用构造器,构造两个新的表,它们的metatable都是Set.mt,对它们进行相加操做的时候,lua会检查第一个参数的metatable中的__add域(metamethods),如果有,就用这个函数进行相加(合集)。
要特别声明一下,假设上述的表和其他类型的数值相加会怎么样?
lua中不关心(可以理解成,不考虑)表和其他类型相加,举个例子:
s + 8
lua会到s的metatable中寻找__add的域,然后它发现第二个操做数不是表,这个__add的函数就会报错。如果要获取具体的报错信息,可以在对_add的函数内部对两个参数加上一层检测,来提示自己是合集操做时出错。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值