table是lua中非常重要的一种数据类型,但是不能直接将两个table类型的数据进行运算(算数运算、关系运算)。通过给table类型的数据设置元表(metatable)可以解决该问题,但是元表的功能不仅限于此,元表的主要功能有:
(1)定义算术操作符和关系操作符的行为
(2)为 Lua 函数库提供支持
(3)控制对 table 的访问
给数据设置元表的方法为:setmetatable(数据1,数据2) 数据1为需要被设置元表的数据,数据2为元表数据
获取数据的元表的方法为:getmetatable(数据t)
1.算数类的原方法
+ __add
* __mul
- __sub
/ __div
- __unm (for negation)
% __mod
^ __pow
对于连接操作符有对应的 metamethod:__concat
例子:
local mt = {}
function mt.__add(a, b)
return 'table + ' .. b
end
local t = {}
setmetatable(t, mt)
print(t + 1)
2.关系型运算的元方法
== __eq
< __lt
<= __le
其他的关系操作符都是用上面三种表示:
a ~= b 表示为 not (a == b)
a > b 表示为 b < a
a >= b 表示为 b <= a
注意:
(1)关系运算符用于比较拥有不同的 metamethod(而非 metatable)的两个 value 时会产生错误
(2)在整数类型的比较中 a <= b 可以被转换为 not (b < a),但是如果某类型的所有元素并未适当排序,此条件则不一定成立。例如:浮点数中 NaN(Not a Number)表示一个未定义的值,NaN <= x 总是为 false 并且 x < NaN 也总为 false。
3.为Lua库函数提供支持
__tostring 用print打印时会调用tostring方法
__metatable 设置该域后,getmetatable 将返回此域,而 setmetatable 则会产生一个错误
例子:
mt.__metatable = "not your business"
local t = {}
setmetatable(t, mt)
print(getmetatable(t)) --> not your business
setmetatable(t, {})
stdin:1: cannot change protected metatable
4.控制table访问的元方法
__index 在我们访问 table 的不存在的域时,Lua会尝试调用__index元方法。__index域也可以是一个table,那么Lua会尝试在 __index table中访问对应的域
__newindex 如果对 table 的一个不存在的域赋值时,Lua 将检查 __newindex 元方法: (1)如果 __newindex 为函数,Lua 将调用函数而不是进行赋值 (2)如果 __newindex 为一个 table,Lua 将对此 table 进行赋值
通过__index与__newindex元方法可以实现很多功能:
(1)面向对象编程
(2)具有默认值的table
(3)跟踪table的访问
(1)定义算术操作符和关系操作符的行为
(2)为 Lua 函数库提供支持
(3)控制对 table 的访问
给数据设置元表的方法为:setmetatable(数据1,数据2) 数据1为需要被设置元表的数据,数据2为元表数据
获取数据的元表的方法为:getmetatable(数据t)
1.算数类的原方法
+ __add
* __mul
- __sub
/ __div
- __unm (for negation)
% __mod
^ __pow
对于连接操作符有对应的 metamethod:__concat
例子:
local mt = {}
function mt.__add(a, b)
return 'table + ' .. b
end
local t = {}
setmetatable(t, mt)
print(t + 1)
2.关系型运算的元方法
== __eq
< __lt
<= __le
其他的关系操作符都是用上面三种表示:
a ~= b 表示为 not (a == b)
a > b 表示为 b < a
a >= b 表示为 b <= a
注意:
(1)关系运算符用于比较拥有不同的 metamethod(而非 metatable)的两个 value 时会产生错误
(2)在整数类型的比较中 a <= b 可以被转换为 not (b < a),但是如果某类型的所有元素并未适当排序,此条件则不一定成立。例如:浮点数中 NaN(Not a Number)表示一个未定义的值,NaN <= x 总是为 false 并且 x < NaN 也总为 false。
3.为Lua库函数提供支持
__tostring 用print打印时会调用tostring方法
__metatable 设置该域后,getmetatable 将返回此域,而 setmetatable 则会产生一个错误
例子:
mt.__metatable = "not your business"
local t = {}
setmetatable(t, mt)
print(getmetatable(t)) --> not your business
setmetatable(t, {})
stdin:1: cannot change protected metatable
4.控制table访问的元方法
__index 在我们访问 table 的不存在的域时,Lua会尝试调用__index元方法。__index域也可以是一个table,那么Lua会尝试在 __index table中访问对应的域
__newindex 如果对 table 的一个不存在的域赋值时,Lua 将检查 __newindex 元方法: (1)如果 __newindex 为函数,Lua 将调用函数而不是进行赋值 (2)如果 __newindex 为一个 table,Lua 将对此 table 进行赋值
通过__index与__newindex元方法可以实现很多功能:
(1)面向对象编程
(2)具有默认值的table
(3)跟踪table的访问