在Lua中的类中使用self关键字

时间:2014-12-27 13:19:29

标签: lua lua-table

我知道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

2 个答案:

答案 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中,并且每个表都有一个列表中下一个或上一个表的记录。