在前面的笔记中有提到,当对table使用 ‘+’ 的时候,会去查找table的metatable有没有相应的__add metamathods。用运算符触发table的metatable是lua核心提供的。
实际上,metatable是一张普通的表,其他的操做也是可以触发table的metatable的。
在lua提供的库中,有部分函数,就是如此,比如说tostring。
在print函数输出一个对象的时候,会先调用tostring去对这个对象格式化,然后输出,如果这个对象是table,tostring会先去寻找这个table的metatable中是否有__tostring metamathods,如果有就会调用它进行格式化。
代码如下:
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.tostring(set)
local s = "{"
local sep = ""
for k in pairs(set) do
s = s..sep..k
sep = ", "
end
s = s.."}"
return s
end
do
Set.mt.__tostring = Set.tostring
s1 = Set.New{10,20,30,40}
s2 = Set.New{1,2,10,20}
print(s1)
end
把Set.mt的__tostring指向Set.tostring之后。
所有以Set.mt为metatable的table,在用print输出的时候,过程如下:
print(s) –> tostring(s) –>__tostring(s)
最后 __tostring 调用的结果会返回给print打印