LUA教程库定义的Metamethods-54

tostring是一个典型的例子。如前面我们所见,tostring以简单的格式表示出table:

print({})     --> table: 0x8062ac0

(注意:print函数总是调用tostring来格式化它的输出)。然而当格式化一个对象的时候,tostring会首先检查对象是否存在一个带有__tostring域的metatable。如果存在则以对象作为参数调用对应的函数来完成格式化,返回的结果即为tostring的结果。
在我们集合的例子中我们已经定义了一个函数来将集合转换成字符串打印出来。因此,我们只需要将集合的metatable的__tostring域调用我们定义的打印函数:

Set.mt.__tostring = Set.tostring

这样,不管什么时候我们调用print打印一个集合,print都会自动调用tostring,而tostring则会调用Set.tostring:

s1 = Set.new{10, 4, 5}
 
print(s1)     --> {4, 5, 10}

setmetatable/getmetatable函数也会使用metafield,在这种情况下,可以保护metatables。假定你想保护你的集合使其使用者既看不到也不能修改metatables。如果你对metatable设置了__metatable的值,getmetatable将返回这个域的值,而调用setmetatable 将会出错:

Set.mt.__metatable = "not your business"
s1 = Set.new{}
print(getmetatable(s1))     --> not your business
setmetatable(s1, {})
stdin:1: cannot change protected metatable

发布日期:

所属分类: 编程 标签:


没有相关文章!