我不确定将Stack的元方法设置为Stack的意义是什么。
我环顾四周,但没有一个解释太有意义。我知道有时某些实例可能需要依靠Stack丢失所有方法,但希望得到更清晰的解释。
Stack = {}
Stack.__index = Stack
答案 0 :(得分:0)
比方说,您有一个具有.x
和.y
的“ 2d向量”“类”。您为他们编写了一个dotproduct
函数:
function dotproduct(a, b)
return a.x * b.x + a.y * b.y
end
让您编写foo:dot(bar)
的最简单方法是在每个新实例上放置一个.dot
属性:
-- Make a "V2" namespace
local V2 = {}
function V2.new(x, y)
return {
x = x,
y = y,
-- Attach any methods to the object, also
dot = dotproduct,
}
end
但是,随着方法数量的增加,这种情况变得更糟,原因有两个。一个是您的对象变大了-即使您只需要在每个向量上保留两个数字,大多数散列表都是始终相同的函数!另一个是,多个构造函数会变得很困难,因为您需要在每个构造函数中重复工作。
对此的一种解决方案是__index
元表。不必将每个方法复制到每个新对象上,只需指向所需的“丢失”方法的位置即可:
V2.dot = dotproduct
function V2.new(x, y)
return setmetatable({x = x, y = y}, {__index = V2})
end
此设计有一个小缺点。首先,除了每个表外,还要分配一个新的元表,这会浪费内存(所有元表都是相同的)。其次,如果没有增长这个新的元表(与以前一样的烦恼),您将没有机会覆盖其他方法。
因此,我们只将V2
设为单个元表:
V2.__index = V2
function V2.new(x, y)
return setmetatable({x = x, y = y}, V2)
end