假设用table来表示集合,用function去计算集合的交集、并集。

为了保持名称空间的整齐,将这些函数存入一个名为Set的table中。

现在,假设用“+”来计算两个集合的并集,那么就要让所有用于表示集合的table共享一个元表。

并且在该元表中定义如何执行一个加法操作。

local mt = {}     --集合的元表
function Set.new(l)
local set = {}
setmetatable(set,mt)
for _,v in ipairs(l) do set[v] = true end
return set
end

在此后,用Set.new创建的集合都具有一个相同的元表:

s1 = Set.new{,,,}
s2 = Set.new{,}
print(getmetatable(s1)) -->table:00672B60
print(getmetatable(s2)) -->table:00672B60

最后将元方法加入到元表中:

mt.__add = Set.union

元方法就是一个函数:

Set = {}
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 l = {} --用于存放集合中所有元素的列表
for e in pairs(set) do
l[#l + ] = e
end
return "{" .. table.concat(l,", ") .. "}"
end function Set.print(s)
print(Set.tostring(s))
end

此后,只要Lua试图将两个集合相加,就会调用Set.union函数,并将两个操作数作为参数传入。可以使用加号来求集合的并集:

s3 = s1 + s2
Set.print(s3) --> {1, 10, 20 ,30 ,50}

类似还可以用乘号来求集合的交集:

mt.__mul = Set.intersection
Set.print((s1+s2) * s1) -->{10, 20, 30 ,50}

在元表中,每种算术操作符都有对应的字段名。除了上面的__add和 __mul外,还有__sub,__div、__unm(相反数)、__mod(取模)和__pow(乘幂)。

此外,还可以定义__concat字段,用于描述连接操作符的行为。

然而,当一个表达式中混合了具有不同元表的值时,例如:

s = Set.new{,,}
s = s +

Lua会按照下面步奏去找元表:

如果第一个值有元表,并且元表中有__add字段,那么Lua就以这个字段为元方法,而与第二个值无关;

反之,如果第二个值有元表并包含__add字段,Lua就以它为元方法;

如果两个都没有元方法,Lua就引发一个错误。

Lua可以包含这些混合类型,但实际需要注意如果执行了s = s + 8,那么在Set.union内部就会发生错误。

bad argument # to "pairs" (table expected , got number)

如果想要得到更清晰的错误消息,则必须在实际操作前显式地检查操作数的类型:

function Set.union(a,b)
  if getmetatable(a) ~= mt or getmetatable(b) ~= mt then
    error("attempt to 'add' a set with a non-set value",)
  end
  <as before>

注意,error的第二个参数用于指示哪个函数调用造成了该错误消息。

以上内容来自:《Lua程序设计第二版》和《Programming in Lua  third edition 》

chapter 13_1 算术类的元方法的更多相关文章

  1. chapter 13_3 table访问的元方法

    前两节的算术类.关系类运算符的元方法都为各种错误情况定义了行为,它们不会改变语言的常规行为. 但是Lua还提供了两种可以改变table行为的方法: 一种是查询table中不存在的字段.一种是修改tab ...

  2. chapter 13_2 关系类、库定义的元方法

    元表还可以指定关系操作符的含义,元方法为__eq ,__lt(小于) ,__le(小于等于). 而其它3个关系操作符则没有单独的元方法,Lua会 把a ~= b 转化为not(a == b) 将a&g ...

  3. Lua 学习笔记(十一)元表与元方法

    在Lua中的每个值都有一套预定义的操作集合.例如可以将数字相加,可以连接字符串,还可以在table中插入一对key-value等.但是我们无法将两个table相加,无法对函数作比较,也无法调用一个字符 ...

  4. lua元表和元方法 《lua程序设计》 13章 读书笔记

    lua中每个值都有一个元表,talble和userdata可以有各自独立的元表,而其它类型的值则共享其类型所属的单一元表.lua在创建table时不会创建元表. t = {} print(getmet ...

  5. lua metatable和metamethod元表和元方法

    Lua中提供的元表是用于帮助Lua数据变量完成某些非预定义功能的个性化行为,如两个table的相加.假设a和b都是table,通过元表可以定义如何计算表达式a+b.当Lua试图将两个table相加时, ...

  6. Lua中的元表与元方法

    [前言] 元表对应的英文是metatable,元方法是metamethod.我们都知道,在C++中,两个类是无法直接相加的,但是,如果你重载了“+”符号,就可以进行类的加法运算.在Lua中也有这个道理 ...

  7. Lua中的元表与元方法学习总结

    前言 元表对应的英文是metatable,元方法是metamethod.我们都知道,在C++中,两个类是无法直接相加的,但是,如果你重载了"+"符号,就可以进行类的加法运算.在Lu ...

  8. Step By Step(Lua元表与元方法)

    Step By Step(Lua元表与元方法) Lua中提供的元表是用于帮助Lua数据变量完成某些非预定义功能的个性化行为,如两个table的相加.假设a和b都是table,通过元表可以定义如何计算表 ...

  9. lua元表与元方法

    lua中提供的元表(metatable)与元方法(metamethod)是一种非常重要的语法,metatable主要用于做一些类似于C++重载操作符式的功能. lua中提供的元表是用于帮助lua变量完 ...

随机推荐

  1. Alyona and copybooks

    题目连接 题意: 给 n,a,b,c四个数,n为已有的书的数目,问再买k本书所需花费最少是多少,(k+n)%4==0: 有三种套餐 第一种只有一本书,花费a 第二种有两本书,花费b, 第三种有三本书, ...

  2. android app安全问题设置

    1.应用签名未校验风险:检测 App 程序启动时是否校验签名证书. 2.应用数据任意备份风险 Android 2.1 以上的系统可为 App 提供应用程序数据的备份和恢复功能,该 由 AndroidM ...

  3. php相关书籍视频

    虽然如今web领域,PHP JSP .NET 并驾齐驱,但PHP用的最广,原因不用我多说. 首先发一个PHP手册,方便查询,这个肯定是学PHP必备的.  下载地址:http://u.115.com/f ...

  4. 更改pip源

    ~/.pip/下新建pip.conf文件:(Windows下载Users/xxx/pip/pip.ini) [global] trusted-host = pypi.douban.com index- ...

  5. HNTX_PC 代码总结

    记录一些 汇农 PC 端的代码 CSS 部分 1. 小三角 源自: 司徒正美 Sass >> JS 部分 1. 限制文本内容溢出 2. 固定右侧宽度 4. 用 iframe 加载的页面 C ...

  6. 观察者模式 C++11

    #include <functional> #include <vector> #include <algorithm> #include <iostream ...

  7. Redis 的几种数据结构&五种数据类型对象

    先看几种数据结构 通过分析底层的数据结构,学习如何根据场景选型和设计 1,简单动态字符串 redis使用的字符串SDS有别于C语言中的字符串 a, 结构 free字段为已分配但未使用的空间 len为已 ...

  8. 使用$_SERVER['HTTP_HOST']时需注意的

    在php中,我们一般通过$_SERVER['HTTP_HOST']来活得URL中网站的域名或者ip地址. $_SERVER['HTTP_HOST']在客户的环境里,取得的值总是程序所在的服务器在其局域 ...

  9. 精通javasCRIPT-学习笔记 Features,Functions,Object

    关于学习javasCRIPT的书,市面上太多了,有犀牛书,红宝书,但是他们都类似于一本书,包含js的一切,并没有站在一个高度上,看js的本质,我计划看一看jquery作者resig写的<精通ja ...

  10. 在Eclipse中设置文件的默认打开方式

    在Eclipse中,我们可以设置jsp.xml.js.sql等文件默认打开方式: ①.打开配置选项 ②.找到文件设置 ③.选中我们要设置的文件,默认即可: