我知道Lua中的“self”与Java中的“this”类似。 “this”表示Java中的当前对象,但我知道Java是面向对象的,而Lua是基于原型的。任何人都可以解释为什么下面的代码必须使用“self.last”而不是“self”来访问链表的当前节点?谢谢。 :)
list = {}
list.__index = list
setmetatable(list, { __call = function(_, ...)
local t = setmetatable({length = 0}, list)
for _, v in ipairs{...} do t:push(v) end
return t
end })
function list:push(t)
if self.last then
self.last._next = t
t._prev = self.last
self.last = t
else
self.first = t
self.last = t
end
self.length = self.length + 1
end
答案 0 :(得分:2)
程序中有两种不同的对象:列出对象和节点。列表对象管理一系列链接节点,并具有以下字段:
listobject = {
length = 0, -- number of nodes managed by this list object
first = nil, -- reference to first node in this list; nil if list is empty
last = nil -- reference to last node in this list; nil if list is empty
}
对第一个节点的引用对于迭代和前置到列表很有用,而last
引用允许有效的追加。 List对象也有一个metatable,以便您可以调用它们的方法:
listobject:push( {"node1"} )
除非你做一些有趣的事情,self
方法的push
参数将始终是列表对象,而不是节点。
另一方面,节点引用了链中的下一个和上一个节点:
node = {
_next = nil, -- might be nil if not in list or last node
_prev = nil, -- might be nil if not in list or first node
-- plus some data
}
因此,在push
方法中,您访问self.last
以检查列表是否为空(您可以检查self.length
),如果不是,则查找最后一个当前列表中的节点,您可以将作为参数传递的新节点附加到push
。完成后,显然必须更新列表对象中的last
(和first
)引用。列表对象(self
方法体内的push
)不是节点链的一部分。
答案 1 :(得分:0)
self
用于访问调用列表的上一个参数。
例如,如果您致电list({"Hello"}, {"world"}, {"my"}, {"name"}, {"is"})
,list:push
将被称为五次次。每个参数都有一个电话。
如果没有指定 last (这是self.last
)参数(第一个参数就是这种情况),它会将{"Hello"}
设置为t = {"Hello"}; t.first = t; t.last = t;
(自我引用表)。
如果它是第二个以后,它告诉上一个表({"Hello"}
)下一个表是{"my"}
,告诉{"my"}
上一个表是什么,还设置整个"列表中的当前表"最后。请记住,list:push(t)
被多次调用。这意味着self.last被多次调用,但是在实例化列表之后,只有一个表(最后一个参数)在self.last
中,并且每个表都有一个列表中下一个或上一个表的记录。